当Mysql在where子句中不存在时,为什么决定对Order By子句中指定的列使用索引?

时间:2019-04-11 18:07:47

标签: mysql indexing

为什么Mysql决定对Order By子句中指定的列使用索引,尽管where子句中不存在该列? 当在查询中同时使用Order By + Limit子句时,就会发生这种情况。

查询示例:

str

table_name有900万条记录

在没有限制条款的情况下,    mysql使用col1列上的索引,该索引更快。

1 个答案:

答案 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也会出现类似的问题。