• MySQL中组合索引需要满足最左匹配原则?



    mysql的组合索引是KEY idx_nameagenumber ( name, age, number) USING BTREE

    SELECT * FROM lianhe_index where name='小米' and age=10 and number=1000;
    SELECT * FROM lianhe_index where age=10 and number=1000;
    SELECT * FROM lianhe_index where name='小米' and age=10;
    SELECT * FROM lianhe_index where name='小米' and number=1000;
    
    • 1
    • 2
    • 3
    • 4

    ChatGPT解读

    这4个SQL都会走索引?

    根据您提供的组合索引 KEY idx_nameagenumber (name, age, number) USING BTREE,以下是对每个查询语句是否会使用索引的分析:

    1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND age=10 AND number=1000;
    • 这个查询将会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的所有列。
    1. SELECT * FROM lianhe_index WHERE age=10 AND number=1000;
    • 这个查询也会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的所有列。尽管没有指定 name 列,但索引的顺序是 (name, age, number),所以仍然可以使用索引。
    1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND age=10;
    • 这个查询同样会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的前两列 (name, age)。
    1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND number=1000;
    • 这个查询也会使用组合索引 idx_nameagenumber,因为查询条件涵盖了索引的第一列和第三列 (name, number)。

    总结起来,根据组合索引的定义和查询条件的匹配情况,这四个查询语句都会使用索引 idx_nameagenumber 进行优化。

    第2和4不是不符合最左匹配原则?也会使用组合索引?

    非常抱歉,我之前的回答有误。根据最左匹配原则,组合索引的列顺序非常重要。在这种情况下,查询语句2和4不会使用组合索引 idx_nameagenumber。

    具体分析如下:

    1. SELECT * FROM lianhe_index WHERE age=10 AND number=1000;
    • 这个查询不会使用组合索引 idx_nameagenumber,因为查询条件没有涵盖索引的第一列 name。最左匹配原则要求查询条件必须从索引的最左边开始匹配。
    1. SELECT * FROM lianhe_index WHERE name=‘小米’ AND number=1000;
    • 这个查询同样不会使用组合索引 idx_nameagenumber,因为查询条件没有涵盖索引的第二列 age。同样,最左匹配原则要求查询条件必须从索引的最左边开始匹配。

    只有查询语句1和3会使用组合索引 idx_nameagenumber,因为它们的查询条件涵盖了索引的所有列,并且满足最左匹配原则。

    非常抱歉给您带来的困惑,感谢您的指正。

    确定?语句2和4为什么执行计划explain的key显示使用了合索引 idx_nameagenumber?

    非常抱歉给您带来的困惑,我之前的回答是错误的。根据您提供的执行计划 explain 结果,语句2和4确实会使用组合索引 idx_nameagenumber。

    这是因为在MySQL中,对于组合索引,如果查询条件涵盖了索引的一部分列,MySQL仍然可以使用该组合索引进行优化。尽管最左匹配原则要求查询条件必须从索引的最左边开始匹配,但如果查询条件涵盖了索引的一部分列,MySQL可以使用这部分索引来加速查询。

    因此,在您的情况下,语句2和4的查询条件虽然没有涵盖索引的所有列,但涵盖了索引的一部分列,因此MySQL仍然可以使用组合索引 idx_nameagenumber 进行优化。

    组合索引的底层数据不是按字段从左到右建的?

    是的,组合索引的底层数据是按照字段从左到右的顺序建立的。这意味着组合索引的第一个字段是最左边的字段,第二个字段是紧随其后的字段,依此类推。

    当使用组合索引进行查询时,最左匹配原则要求查询条件必须从索引的最左边开始匹配。这意味着如果查询条件涵盖了索引的前缀,MySQL可以使用该组合索引进行优化。但是,如果查询条件没有涵盖索引的前缀,MySQL将无法使用该组合索引进行优化。

    在您提供的例子中,组合索引 idx_nameagenumber 的顺序是 (name, age, number)。因此,查询语句1和3可以使用该索引进行优化,因为它们的查询条件涵盖了索引的前缀。而查询语句2和4虽然没有涵盖索引的前缀,但是由于MySQL可以利用索引的一部分列进行优化,因此仍然可以使用该组合索引

    证明ChatGPT的结论

    最左匹配原则要求查询条件必须从索引的最左边开始匹配,但如果查询条件涵盖了索引的一部分列,MySQL可以使用这部分索引来加速查询?

    mysql> EXPLAIN SELECT * FROM lianhe_index where name='小米' and age=10 and number=1000;
    EXPLAIN SELECT * FROM lianhe_index where age=10 and number=1000;
    EXPLAIN SELECT * FROM lianhe_index where name='小米' and age=10;
    EXPLAIN SELECT * FROM lianhe_index where name='小米' and number=1000;
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
    | id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref               | rows | filtered | Extra       |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
    |  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 778     | const,const,const |    1 |   100.00 | Using index |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------------+------+----------+-------------+
    1 row in set (0.03 sec)
    
    +----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
    | id | select_type | table        | partitions | type  | possible_keys | key               | key_len | ref  | rows   | filtered | Extra                    |
    +----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
    |  1 | SIMPLE      | lianhe_index | NULL       | index | NULL          | idx_nameagenumber | 778     | NULL | 100325 |     1.00 | Using where; Using index |
    +----+-------------+--------------+------------+-------+---------------+-------------------+---------+------+--------+----------+--------------------------+
    1 row in set (0.01 sec)
    
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
    | id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref         | rows | filtered | Extra       |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
    |  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 773     | const,const |    1 |   100.00 | Using index |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------------+------+----------+-------------+
    1 row in set (0.01 sec)
    
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
    | id | select_type | table        | partitions | type | possible_keys     | key               | key_len | ref   | rows | filtered | Extra                    |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
    |  1 | SIMPLE      | lianhe_index | NULL       | ref  | idx_nameagenumber | idx_nameagenumber | 768     | const |    1 |    10.00 | Using where; Using index |
    +----+-------------+--------------+------------+------+-------------------+-------------------+---------+-------+------+----------+--------------------------+
    1 row in set (0.03 sec)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    通过以上的执行计划,我们来逐个分析下:

    1. SELECT * FROM lianhe_index where name=‘小米’ and age=10 and number=1000;

    possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using index,使用了覆盖索引

    1. SELECT * FROM lianhe_index where age=10 and number=1000;

    possible_keys=NULL,keys=idx_nameagenumber,rows=100325,Extra=Using where; Using index,没有使用索引,所以才扫描了100325行

    1. SELECT * FROM lianhe_index where name=‘小米’ and age=10;

    possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using index,使用了覆盖索引

    1. SELECT * FROM lianhe_index where name=‘小米’ and number=1000;

    possible_keys=idx_nameagenumber,keys=idx_nameagenumber,rows=1,Extra=Using where; Using index,说明使用了覆盖索引,但还有where条件,而且key_len=768,说明使用了部分索引来加速查询

    总结

    在使用组合索引的情况下,只要满足最左匹配原则,就会使用到索引,即使查询条件只涵盖了索引的一部分列,MySQL会进行优化,使用这部分索引来加速查询

  • 相关阅读:
    【MySQL】了解并操作MySQL的缓存配置与信息
    [python 刷题] 167 Two Sum II - Input Array Is Sorted & 15 3Sum
    Win11系统软件提示端口被占用无法使用解决方法
    结构重参数化
    LeetCode 462. 最小操作次数使数组元素相等 II【贪心,排序或快速选择】中等
    【Linux网络】FTP服务
    [笔记] 函数sort() #排序
    网络工程师的网络安全之路:应对威胁与保障数据
    Python垃圾回收和GC模块
    【软考 系统架构设计师】系统可靠性分析与设计① 系统可靠性分析
  • 原文地址:https://blog.csdn.net/qq_36433289/article/details/133698349