简体   繁体   English

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

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

Say that I have a long, expensive query, packed with conditions, searching a large number of rows.假设我有一个长而昂贵的查询,包含条件,搜索大量行。 I also have one particular condition, like a company id, that will limit the number of rows that need to be searched considerably, narrowing it down to dozens from hundreds of thousands.我还有一个特定条件,例如公司 ID,它将限制需要大量搜索的行数,将搜索范围从数十万缩小到数十个。

Does it make any difference to MySQL performance whether I do this:我是否这样做对 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

or this:或这个:

 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) 

Here is a demo showing the order of WHERE clause conditions can make a difference due to short-circuiting.这是一个演示,显示 WHERE 子句条件的顺序因短路而产生影响。 It runs the following queries:它运行以下查询:

-- 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;

The only difference between these is the order of operands in the OR condition.它们之间的唯一区别是OR条件中操作数的顺序。

myslowfunction deliberately sleeps for a second and has the side effect of adding an entry to a log table each time it is run. myslowfunction故意休眠一秒钟,并具有在每次运行时向日志表添加条目的副作用。 Here are the results of what is logged when running the two queries:以下是运行这两个查询时记录的结果:

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

The above shows that a slow function is executed more times when it appears on the left side of an OR condition when the other operand isn't always true.上面显示,当另一个操作数不总是为真时,当慢函数出现在OR条件的左侧时,它会执行更多次。

So IMO the answer to the question:所以 IMO 这个问题的答案是:

Does the order of conditions in a WHERE clause affect MySQL performance? WHERE 子句中的条件顺序是否会影响 MySQL 性能?

is "Sometimes it can do."是“有时它可以做到”。

No, the order should not make a large difference.不,顺序不应该有很大的不同。 When finding which rows match the condition, the condition as a whole (all of the sub-conditions combined via boolean logic) is examined for each row.在查找与条件匹配的行时,会检查每一行的整个条件(通过布尔逻辑组合的所有子条件)。

Some intelligent DB engines will attempt to guess which parts of the condition can be evaluated faster (for instance, things that don't use built-in functions) and evaluate those first, and more complex (estimatedly) elements get evaluated later.一些智能数据库引擎会尝试猜测条件的哪些部分可以更快地评估(例如,不使用内置函数的东西)并首先评估那些,然后评估更复杂(估计)的元素。 This is something determined by the DB engine though, not the SQL.这是由数据库引擎决定的,而不是由 SQL 决定的。

The order of columns in your where clause shouldn't really matter, since MySQL will optimize the query before executing it. where 子句中的列顺序并不重要,因为 MySQL 会在执行之前优化查询。 But I suggest you read the chapter on Optimization in the MySQL reference manual, to get a basic idea on how to analyze queries and tables, and optimize them if necessary.但我建议你阅读 MySQL 参考手册中关于优化的章节,以获得关于如何分析查询和表的基本概念,并在必要时优化它们。 Personally though, I would always try to put indexed fields before non-indexed fields, and order them according to the number of rows that they should return (most restrictive conditions first, least restrictive last).不过就我个人而言,我总是尝试将索引字段放在非索引字段之前,并根据它们应该返回的行数对它们进行排序(首先是最严格的条件,最后是最不严格的条件)。

Mathematically Yes It has an effect.数学上是的它有效果。 Not only in SQL Query.不仅在 SQL 查询中。 rather in all programming languages whenever there is an expression with and / or .而是在所有编程语言中,只要有and / or的表达式。 There works a theory of Complete evaluation or partial evaluation.有一种完全评价或部分评价的理论。 If its an and query and first expression of and evaluates to false it will not check further.如果它的一个与查询的第一表达and计算结果为假时,将不会进一步检查。 as anding false with anything yields false . as anding false 任何东西都会产生 false 。 Similerly in an or expression if first one is true it will not check further.同样,在 or 表达式中,如果第一个为真,则不会进一步检查。

A sophisticated DBMS should be able to decide on its own which where condition to evaluate first.一个复杂的 DBMS 应该能够自行决定首先评估哪个条件。 Some Databases provide tools to display the "strategy" how a query is executed.一些数据库提供工具来显示如何执行查询的“策略”。 In MySQL, eg you can enter EXPLAIN in front of a query .在 MySQL 中,例如,您可以在查询前输入EXPLAIN The DBMS then prints the actions it performed for executing the query, as eg index or full-table scan.然后 DBMS 打印它为执行查询而执行的操作,例如索引或全表扫描。 So you could see at a glance whether or not it uses the index for 'company' in both cases.因此,您可以一目了然地看到它是否在这两种情况下都使用了“公司”的索引。

this shouldn't have any effect, but if you aren't sure, why don't you simply try it out?这不应该有任何影响,但是如果您不确定,为什么不简单地尝试一下呢? the order of where-clauses on an select from a single table makes no difference, but if you join multiple tables, the order of the joins could affect the performace (sometimes).从单个表中选择的 where 子句的顺序没有区别,但是如果您连接多个表,连接的顺序可能会影响性能(有时)。

I don't think the order of the where clause has any impact.我认为 where 子句的顺序没有任何影响。 I think the MySQL query optimizer will reorganize where clauses as it sees fit so it filters away the largest subset first.我认为 MySQL 查询优化器会按照它认为合适的方式重新组织 where 子句,因此它首先过滤掉最大的子集。

It's another deal when talking about joins.在谈论连接时,这是另一回事。 The optimizer tries to reorder here too, but doesn't always finds the best way and sometimes doesn't use indexes.优化器也尝试在此处重新排序,但并不总能找到最佳方式,有时也不使用索引。 SELECT STRAIGHT JOIN and FORCE INDEX let's you be in charge of the query. SELECT STRAIGHT JOIN 和 FORCE INDEX 让您负责查询。

No it doesn't, the tables required are selected and then evaluated row by row.不,不是,需要的表被选中,然后逐行评估。 Order can be arbitrary.顺序可以任意。

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

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