WHERE子句中的条件顺序是否会影响MySQL性能?

时间:2010-06-15 06:44:29

标签: mysql sql

假设我有一个冗长,昂贵的查询,包含条件,搜索大量行。我还有一个特殊的条件,比如公司ID,它将限制需要大量搜索的行数,将其缩小到数十万甚至数十万。

我是否这样做对MySQL性能有什么影响:

 SELECT * FROM clients WHERE 
       (firstname LIKE :foo OR lastname LIKE :foo OR phone LIKE :foo) AND 
       (firstname LIKE :bar OR lastname LIKE :bar OR phone LIKE :bar) AND 
       company = :ugh

或者这个:

 SELECT * FROM clients WHERE 
       company = :ugh AND
       (firstname LIKE :foo OR lastname LIKE :foo OR phone LIKE :foo) AND 
       (firstname LIKE :bar OR lastname LIKE :bar OR phone LIKE :bar) 

8 个答案:

答案 0 :(得分:19)

这是一个在线演示,显示WHERE子句条件的顺序可以因短路而产生影响:

http://rextester.com/HJGN96158

这将运行以下查询:

-- query #1
SELECT myint FROM mytable WHERE myint >= 3 OR myslowfunction('query #1', myint) = 1;

-- query #2
SELECT myint FROM mytable WHERE myslowfunction('query #2', myint) = 1 OR myint >= 3;

这些之间的唯一区别是OR条件中操作数的顺序。

myslowfunction故意睡眠一秒,并且每次运行时都会在日志表中添加一个条目。以下是运行上述两个查询时记录的结果:

myslowfunction called for query #1 with value 1
myslowfunction called for query #1 with value 2
myslowfunction called for query #2 with value 1
myslowfunction called for query #2 with value 2
myslowfunction called for query #2 with value 3
myslowfunction called for query #2 with value 4

上面显示当一个慢速函数出现在OR条件的左侧时,当另一个操作数不总是为真时,它会被执行多次。

所以IMO回答了这个问题:

  

WHERE子句中的条件顺序是否会影响MySQL的性能?

是“有时可以做到。”

答案 1 :(得分:16)

不,订单不应该有很大的不同。当找到哪些行匹配条件时,将检查每一行的条件(通过布尔逻辑组合的所有子条件)。

一些智能数据库引擎会尝试猜测可以更快地评估条件的哪些部分(例如,不使用内置函数的事物)并首先评估这些部分,并且稍后评估更复杂(估计)的元素。这是由数据库引擎决定的,而不是SQL。

答案 2 :(得分:5)

where子句中列的顺序并不重要,因为MySQL会在执行之前优化查询。但我建议您阅读MySQL参考手册中有关Optimization的章节,以获得有关如何分析查询和表格的基本概念,并在必要时对其进行优化。就个人而言,我总是会尝试将索引字段放在非索引字段之前,并根据它们应返回的行数进行排序(最先限制条件最多,最后限制最少)。

答案 3 :(得分:4)

复杂的DBMS应该能够自己决定哪个条件首先要评估。某些数据库提供了用于显示查询执行方式的“策略”的工具。在MySQL中,例如你可以输入EXPLAIN in front of a query。然后,DBMS打印它为执行查询而执行的动作,例如,索引或全表扫描。因此,您可以一眼看出它是否在两种情况下都使用“公司”索引。

答案 4 :(得分:4)

数学上是它有效果。不仅在SQL Query中。而且只要有and / or的表达式,就在所有编程语言中。 有完整评估或部分评估的理论。 如果它的{和and的查询和第一个表达式的计算结果为false,则不会进一步检查。因为任何东西都是虚假的。 如果第一个是真的,则在一个或表达式中,它将不会进一步检查。

答案 5 :(得分:3)

这不应该有任何影响,但如果你不确定,为什么不简单地尝试一下呢?从单个表中选择where子句的顺序没有区别,但如果连接多个表,则连接的顺序可能会影响性能(有时)。

答案 6 :(得分:3)

我认为where子句的顺序没有任何影响。我认为MySQL查询优化器会重新组织where子句,因为它首先过滤掉最大的子集。

谈论加入时,这是另一项协议。优化器也试图在这里重新排序,但并不总是找到最好的方法,有时不使用索引。 SELECT STRAIGHT JOIN和FORCE INDEX让你负责查询。

答案 7 :(得分:1)

否则不会选择所需的表,然后逐行进行评估。订单可以是任意的。