假设我有一个冗长,昂贵的查询,包含条件,搜索大量行。我还有一个特殊的条件,比如公司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)
答案 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)
否则不会选择所需的表,然后逐行进行评估。订单可以是任意的。