高性能SQL语句权威指南

大多数人都忘记了查询语句只是应用sql的第一步。确保查询语句更加适合上下文和性能优异是下一步需要做的事情。这篇SQL教学文章将教你如何评价你的sql查询语句的优劣。

3. 不要让语句承担超出他们本身的查询任务

数据类型转换引导你进入下一个优化点:你不应该过度设计你的语句。确保它们简单有效。当查询语句可能变得复杂时,那么确保它们简单和有效看起来是必然的。然而,接下来你将看到一个例子,一个你十分可能将其简单的语句设计的复杂的例子。

** OR操作符

当你在语句中使用’OR’操作符时,查询语句不会使用索引查询。 时刻牢记索引是一种可以提高数据库表的检索速度的数据结构,但是这一提高必须付出代价:你必须增加写入次数以及提供保存索引的存储空间。索引使得查询定位数据库表的数据时不需要检索每一行数据。你可以给数据库表中的一个或多个列创建索引。如果你不使用索引,那么你的查询将耗费更多时间。这就是为什么需要在你的查询语句中替换掉’OR’操作符的原因。 考虑下以下语句

SELECT driverslicensenr, name 
FROM Drivers 
WHERE driverslicensenr = 123456 
OR driverslicensenr = 678910 
OR driverslicensenr = 345678;

你可以使用以下操作符对其进行替换

  • 使用IN 替换or
SELECT driverslicensenr, name 
FROM Drivers 
WHERE driverslicensenr IN (123456, 678910, 345678);
  • 对两条’SELECT’语句使用’UNION’ 提示:此处,你需要非常小心的使用’UNION’操作符,因为可能会对同样的表进行数次不必要操作。同时,当你使用’UION’时,语句执行时间会变慢.可以将’UNION’操作符替换:将所有的查询置于一条SELECT指令中,或者使用’OUTER JOIN’代替’UNION’. 提示:这里也需要注意一点,尽管’OR’和在下面提到的其他一些操作符不适用索引,但这并不是说索引总是最好的选择。 ‘NOT’操作符

当你的查询语句包含’NOT’操作符时,它也不会使用索引,就像’OR’一样.这将使你的查询语句变慢.如果你不理解,看看下面的例子:

SELECT driverslicensenr, name 
FROM Drivers 
WHERE NOT (year > 1980);

毫无疑问这条语句将比你预期的运行时间久,运行慢的主要原因是其过于复杂:我们可以像这样寻找替代方案。考虑一下用比较运算符替换not,例如:’>’,’!’,’>’;这些例子可以将上文中的语句修改成这样:

`SELECT driverslicensenr, name FROM Drivers WHERE year <= 1980;`

现在看起来整洁多了,难道不是吗? ‘AND’操作符 ‘AND’操作符是一种不使用索引的操作符。如果以一种复杂低效的方式使用,你的查询语句将会变得很慢。就像下面的例子:

SELECT driverslicensenr, name 
FROM Drivers 
WHERE year >= 1960 AND year <= 1980;

最好使用’BETWEEN’操作符重写语句:

SELECT driverslicensenr, name 
FROM Drivers 
WHERE year BETWEEN 1960 AND 1980;

‘ANY’和’ALL’操作符

‘ALL’和’ANY’也是你需要小心使用的操作符,因为当你的语句中包含这些操作符时,语句将不会使用索引。此处应当使用功能函数’MIN’或者’MAX’替换它。

提示 :当你在此处替换原有语句时,你应该意识到聚集函数像’SUM’,’AVG’,’MIN’,’MAX’可能导致非常长的查询语句。基于此,你也可以试着去减少一次处理行的数量。我们再一次意识到,当决定使用你的查询语句时,确定你的环境以及语句目的是十分重要的。

以一定条件将列隔离

当列参与计算和标记时,索引无法使用。一个可能的解决方案是仅仅隔离特定的列,以至于它不再参与计算或者函数功能.考虑如下例子:

SELECT driverslicensenr, name 
FROM Drivers 
WHERE year + 10 = 1980;

这看起来很时髦,不是吗?一种替换方案是,试着去考虑将这条语句修改成这样:

SELECT driverslicensenr, name 
FROM Drivers 
WHERE year = 1970;

不要强制执行

最后一个要点事实上是你不应该尝试去过多限制你的查询语句,因为这可能会影响它的性能。在使用join和having时,这是必须要特别注意的地方。

表的顺序

当你连接两张表时,考虑其连接顺序是相当重要的。如果一张表比其它表都大,你可能想要重写你的查询语句,从而使得这个最大的表被放置在连接的最后。

Joins中的冗余条件

当在你的joins中加入太多条件后,事实上你的sql会选择某些执行顺序。尽管如此,这个顺序可能不是最优的执行路径。

‘HAVING’的守则

使用’HAVING’应当将其加入原始的SQL因为’Where’关键字不能用在集合函数中。’HAVING’通常在’GROUP BY’中使用一些条件来限制返回行的组.然而,如果你在你的语句中这样做,它将不会使用索引,正如你所知道的那样,这样会影响其执行性能。

如果你想寻找一种替换机制,考虑一下’WHERE’.看看下面的语句:

SELECT state, COUNT(*) 
FROM Drivers 
WHERE state IN ('GA', 'TX') 
GROUP BY state 
ORDER BY state
SELECT state, COUNT(*) 
FROM Drivers 
GROUP BY state 
HAVING state IN ('GA', 'TX') 
ORDER BY state

第一个查询语句使用’WHERE’限制统计行的数量,然而第二个查询语句使用’HAVING’来统计。在这些案例的类型中,使用where显然更好,因为这样你不会浪费任何资源。

你认为这和限制结果集没有关系,而关于限制语句中间查询的记录。

注意一下在两种方式之间的不同,’where‘事实上有条件的获得了一个单独的列,而’HAVING’事实上获得了一个结果集或者选择了一个单独的结果,例如’MIN’,’MAX’,’SUM’,..的结果从多个列产生。

你看到的,评价语句质量,写与优化sql语句不是一件容易的事情,特别是你考虑使性能达到最优的时候;避免反模式和考虑可替换的方案也是你责任的一部分,尤其是当你在写的语句需要运行在特定环境的数据中时。

这篇文章仅仅是关于sql语句反模式的概述,可以帮助初学者理解;如果你想更进一步了解高级开发者是如何考虑最频繁的反模式,查看这些讨论: this discussion. Bio: Karlijn Willems is a data science journalist and writes for the DataCamp community, focusing on data science education, the latest news and the hottest trends. She holds degrees in Literature and Linguistics and Information Management.

Original. Reposted with permission.

Related:

    原文作者:SQL
    原文地址: https://juejin.im/entry/59af6a676fb9a02484495470
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞