美文网首页
MySQL ORDER GROUP 索引问题探讨

MySQL ORDER GROUP 索引问题探讨

作者: 七秒钟回忆待续 | 来源:发表于2022-03-05 15:40 被阅读0次

    MySQL 版本: SELECT VERSION(); // 8.0.23

    组合索引相关的文档:https://dev.mysql.com/doc/refman/8.0/en/multiple-column-indexes.html
    EXPLAIN输出相关文档:https://dev.mysql.com/doc/refman/8.0/en/explain-output.html
    SQL的执行顺序:https://www.eversql.com/sql-order-of-operations-sql-query-order-of-execution/

    DDL

    CREATE TABLE `dev` (
      `id` int NOT NULL AUTO_INCREMENT,
      `x` int NOT NULL DEFAULT '0',
      `y` int NOT NULL DEFAULT '0',
      `z` int NOT NULL DEFAULT '0',
      `m` int NOT NULL DEFAULT '0',
      `n` int NOT NULL DEFAULT '0',
      PRIMARY KEY (`id`),
      KEY `idx_x_y_z` (`x`,`y`,`z`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
    

    WHERE 篇

    • EXPLAIN SELECT * FROM dev WHERE x = 1; // type=ref,因此是一种索引访问。
      1.png
    • EXPLAIN SELECT * FROM dev WHERE y = 1; // type=ALL,因此是全表扫描。
      2.png
    • EXPLAIN SELECT x, y, z FROM dev WHERE x = 1 AND y = 2; // type=ref;Extra=Using index。其中Using index表明MySQL使用覆盖索引。
      3.png
    • EXPLAIN SELECT * FROM dev WHERE x > 1 AND y = 2 AND z = 3; // type=range,即范围扫描,也就是有限制的索引扫描。key_len=4表明仅仅用到了x这个索引。(int占4个字节)
      4.png

    简单讲就是最左前缀匹配原则,并且要利用组合索引后面的索引,其前面的索引必须是等值查询(其她各种情况可以试试.......

    ORDER BY 篇

    结合 where 篇的经验,先看看组合索引基于最左前缀匹配原则的等值查询,即x=constant

    • EXPLAIN SELECT * FROM dev WHERE x = 1 ORDER BY y; // Extra=NULL 预期的结果,索引本来就有序,所有order by不用单独排序。
      5.png
    • EXPLAIN SELECT * FROM dev WHERE x = 1 ORDER BY y ASC, z DESC; // Extra=Using filesort 其实也很好理解,组合索引(x,y,z)本来就是有序的,但是在ORDER BY里,yz的顺序是相反的,那必然得进行额外的排序。
      6.png

    非等值查询

    • EXPLAIN SELECT * FROM dev WHERE x = 1 and y > 2 ORDER BY z; // Extra包含Using filesort,因为组合索引(x,y,z)里,虽然x,y都用到了索引,但是y是范围扫描,因此ORDER BY z需要额外的排序。如果ORDEY BY z改为 ORDER BY y 则会利用索引,不会有额外的排序。
      7.png

    GROUP BY篇

    相关文章

      网友评论

          本文标题:MySQL ORDER GROUP 索引问题探讨

          本文链接:https://www.haomeiwen.com/subject/wqzvrrtx.html