为什么where子句的顺序会影响性能?

时间:2016-12-28 07:04:29

标签: mysql query-optimization

我对where子句的排序有疑问。

我从其他问题中看到,where子句的顺序不会影响sql查询的性能,但是当我更改顺序时,我的查询性能会发生变化。

select sql_no_cache idx
from rr
where (timestamp >= '2016-11-28' and timestamp <= '2016-12-28')
  and ((select name from xx where midx=rr.midx) like 'test'

select sql_no_cache idx
from rr
where ((select name from xx where midx=rr.midx) like 'test'
  and (timestamp >= '2016-11-28' and timestamp <= '2016-12-28')

表rr的索引为'idx','midx'和'timestamp'

知道为什么吗?

2 个答案:

答案 0 :(得分:0)

我的猜测是,这是由于短路,基本上只有当时间戳条件为真时才执行子选择。

对于大多数行,当时间戳条件为真时,您可能会获得相同的性能结果。

This SO has some info on this.

And also this one, marked as duplicate as the former.

答案 1 :(得分:0)

如果所有信息都可用,优化工具将查看WHERE的所有部分,然后决定首先执行哪些部分。当订单语义无关时,订单将被忽略。

实际上用作优化的一条规则是首先执行MATCH...AGAINST

然而,在少数情况下(例如你的),优化器不知道哪个部分会更好。因此它希望用户最了解;短路可能会对性能产生巨大影响。

括号不控制顺序,只控制语义。 (通常它们只是多余的。)

(select name from xx where midx=rr.midx) like 'test'可以变为EXISTS (SELECT * FROM xx WHERE midx=rr.midx AND name = 'test') - 优化工具确实理解EXISTS(...)并且比您的制定做得更好。

“table rr在'idx','midx'和'timestamp'上有索引” - 含糊不清。这是三个1列索引吗?还是一个3列复合指数? (存在差异。)这些是可取的:

rr:  INDEX(timestamp)
xx:  INDEX(midx, name)