为什么Mysql决定对Order By子句中指定的列使用索引,尽管where子句中不存在该列? 当在查询中同时使用Order By + Limit子句时,就会发生这种情况。
查询示例:
str
table_name有900万条记录
在没有限制条款的情况下, mysql使用col1列上的索引,该索引更快。
答案 0 :(得分:1)
更好
...
"channelResponse": { //this object contains objects with dynamic names, the number of these objects can change
"Dynamic_Variable_Name": { //This object contains variables and an object containing a list of objects with dynamic names
"conversation":null,
"conversationSubject":null,
"recepientList":{ // the number objects inside this object can be variable
"Dynamic_Variable_Name":{ //this object contains a List objects with dynamic names, the number of this objects can change
"Dynamic_Variable_Name":[{ //Object User
"userId":null, //This is the information that I need
"groupId":null //This is the information that I need
}]
},
"Dynamic_Variable_Name":{
"Dynamic_Variable_Name"[{
"userId":null,
"groupId":null,
}],
"Dynamic_Variable_Name":[{
"userId":null,
"groupId":null,
}],
}
},
"cretedDate":"2019-04-20"
}
}
...
最佳索引是以下两项之一:
select col1, col2,col3
from table_name
where col1 = 'x'
and col3 = 'y'
order by col4
limit 3;
在这两种方法中,优化器都可以完全解析INDEX(col1, col3, col4)
INDEX(col3, col1, col4)
并执行WHERE
甚至由于ORDER BY
而在3行之后停止。
最佳。将LIMIT
添加到任意一个的 end 会获得更好的性能。这使它成为“覆盖”索引,因此所有工作都可以在索引的BTree中完成,而无需触及数据的BTree。
返回您的问题
如果您没有这些索引之一,则优化器陷入困境,通常会从两个可能的选择中选择错误。假设您只有
col2
计划A着重于过滤:使用INDEX(col1), INDEX(col4)
,但在剥离3之前必须对所有匹配的行进行排序。但是它可能会得到一百万行,并且必须对其进行排序。
计划B避免排序:以col1
顺序浏览索引。如果真的很幸运,则前3行将与col4
子句匹配。如果确实不走运,它将扫描整个表,而不会找到3个可接受的行。但是它们会被排序!
“统计信息”微不足道,无法现实地在两个选择之间做出决定。
任何一个计划都可能真的很慢。
在两个表上使用WHERE
子句过滤的JOINs
也会出现类似的问题。