Mysql 为什么where条款的顺序会影响履行?

Mysql 为什么where条款的顺序会影响履行?,mysql,query-optimization,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_cach

我对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”上有索引


知道为什么吗?

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

当大多数行的时间戳条件为true时,您可能会得到相同的性能结果


如果所有信息都可用,优化器将查看WHERE的所有部分,然后决定首先执行哪些部分。如果顺序在语义上不相关,则忽略该顺序

一条规则,实际上是作为一种优化,是首先执行匹配

然而,在一些情况下,例如在您的情况下,优化器不知道哪一部分更好。因此,它转而希望用户知道得最好;短路会对性能产生巨大影响

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

从xx中选择名称,其中midx=rr.midx类似的“test”可以转换为EXISTS从xx中选择*,其中midx=rr.midx和name=“test”-优化器确实了解EXISTS。。。比你的配方做得更好

表rr在“idx”、“midx”和“timestamp”上有索引-不明确。这是三个1列索引吗?还是一个三列综合指数?这有很大的区别。这些都是可取的:

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

因为查询优化器并不完美。谢谢您的回答。你能更具体地解释一下吗?我知道只有当第一个查询的时间戳条件为true时,才会执行sub-select,但为什么不执行第二个查询呢?优化器不应该选择在时间戳上运行索引扫描而不考虑子句顺序吗?“为什么”是一个哲学问题。你遇到的问题真的是哲学问题吗?嗯。。我不这么认为。我只想确定,每次尝试写SQL查询或信任优化程序,我是否必须考虑WHERE子句排序,它会为我做这项工作。因此,我将用另一个问题来回答:优化器如何知道第一个条件比第二个条件好?据我所知,括号将强制某种顺序,根据我的经验,短路确实会影响评估的顺序,但正如我所说,我在这方面没有权威。回答得很好!我要试试这个。谢谢我建议使用IN而不是EXISTS,因为优化器可以选择进行半连接转换,并将子查询转换为连接。换句话说,类似于:从rr中选择idx,其中时间戳介于“2016-11-28”和“2016-12-28”之间,从xx中选择midx,其中名称=“测试”。Rick建议的索引仍然有用。半连接优化直到5.6.10或更高版本才添加@你使用的是什么版本?mysql版本是5.6.28。因此,使用IN似乎是一个不错的选择。:D