MySQL - 查找查询的最佳索引

Posted

技术标签:

【中文标题】MySQL - 查找查询的最佳索引【英文标题】:MySQL - find optimal index for query 【发布时间】:2020-12-04 00:10:21 【问题描述】:

我有疑问:SELECT DISTINCT a1, a2, a3 FROM t WHERE a4 = '' ORDER BY a1, a5

和索引:(a4, a1, a5, a2, a3)

查询说明:Using where; Using index; Using temporary

索引中哪些字段顺序是最佳的或者查询可以优化?

UPD

EXPLAIN FORMAT=JSON SELECT ...:

    
     "query_block": 
       "select_id": 1,
       "temporary_table": 
         "function": "buffer",
         "table": 
           "table_name": "t",
           "access_type": "range",
           "possible_keys": ["my_index"],
           "key": "my_index",
           "key_length": "92",
           "used_key_parts": ["a4"],
           "rows": 113479,
           "filtered": 100,
           "attached_condition": "(t.a4 = '')",
           "using_index": true
         
       
     

【问题讨论】:

没有DISTINCT,我认为你的索引是最好的。请提供EXPLAIN FORMAT=JSON SELECT ... @RickJames 我在问题中添加了信息 如果没有DISTINCT,你会得到多少行? (SELECT COUNT(*) WHERE a4='';) @RickJames 大约 120 000 听起来好像不需要DISTINCT 【参考方案1】:

对于您的查询,最佳索引似乎是:

(a4, a1, a2, a3, a5)
-^ for the where clause
-----^ returned in the select and perhaps used for the select distinct
-----------------^ covers the query so the data pages are not fetched

也就是说,您的查询仍需要对结果进行排序。我认为没有办法使用索引来消除这种情况。

【讨论】:

我添加了你的索引,但是 mysql 从我的两个中挑选。用你的索引查询解释:Using where; Using index; Using temporary; Using filesort @Vv。 . . .在这种情况下,MySQL 不知道如何使用索引进行聚合,因此两者是等价的。其他数据库有更智能的优化器。 @Vv。 - 你用那个索引time了吗? Ans EXPLAIN FORMAT=JSON 对此有何评论?【参考方案2】:

您拥有的索引是该查询所能获得的最佳索引。

DISTINCT 查询修饰符强制查询使用临时表来累积到目前为止的不同行。

但至少您的查询不必读取表格。它仅通过读取索引即可获取所需的所有列。这就是您在 EXPLAIN 中看到的 Using index 注释。这种优势称为“覆盖指数”。

当它使用你的索引时你看不到Using filesort,因为优化器依赖于以(a1, a5) 的顺序读取索引,这正是你想要的(假设所有行都绑定在@的单个值上987654325@。所以不需要对结果做任何额外的排序。

【讨论】:

以上是关于MySQL - 查找查询的最佳索引的主要内容,如果未能解决你的问题,请参考以下文章

阿里二面:MySQL索引是怎么支撑千万级表的快速查找?

MySQL索引是怎么支撑千万级表的快速查找(一.外存储器-磁盘)

查询成本是 MySQL 查询优化的最佳指标吗?

MySQL索引

MySQL----(索引,慢查询)

Mysql优化查询