繁体   English   中英

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

[英]Does the order of conditions in a WHERE clause affect MySQL performance?

假设我有一个长而昂贵的查询,包含条件,搜索大量行。 我还有一个特定条件,例如公司 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) 

这是一个演示,显示 WHERE 子句条件的顺序因短路而产生影响。 它运行以下查询:

-- 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 性能?

是“有时它可以做到”。

不,顺序不应该有很大的不同。 在查找与条件匹配的行时,会检查每一行的整个条件(通过布尔逻辑组合的所有子条件)。

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

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

数学上是的它有效果。 不仅在 SQL 查询中。 而是在所有编程语言中,只要有and / or的表达式。 有一种完全评价或部分评价的理论。 如果它的一个与查询的第一表达and计算结果为假时,将不会进一步检查。 as anding false 任何东西都会产生 false 。 同样,在 or 表达式中,如果第一个为真,则不会进一步检查。

一个复杂的 DBMS 应该能够自行决定首先评估哪个条件。 一些数据库提供工具来显示如何执行查询的“策略”。 在 MySQL 中,例如,您可以在查询前输入EXPLAIN 然后 DBMS 打印它为执行查询而执行的操作,例如索引或全表扫描。 因此,您可以一目了然地看到它是否在这两种情况下都使用了“公司”的索引。

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

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

在谈论连接时,这是另一回事。 优化器也尝试在此处重新排序,但并不总能找到最佳方式,有时也不使用索引。 SELECT STRAIGHT JOIN 和 FORCE INDEX 让您负责查询。

不,不是,需要的表被选中,然后逐行评估。 顺序可以任意。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM