最左匹配原则
作者:互联网
为什么会有这个 最左匹配原则?
答 : mysql 底层使用的索引是 B+ 树 , B+ 树的存放方式是 从左到右依次有序【特定的结构】,我们写sql时用到联合索引,按照索引的数据结构,按照特定的方式写查询 sql 的条件,最大化的提高查询速度。
最左匹配原则是什么?
简单来讲:在联合索引中,只有左边的字段被用到,右边的才能够被使用到。
左边是带头大哥, 必须在
假如我们创建联合索引 create index idx_a_b on shopTable(a,b);
有如下B+树
我们看到 最左边的a 都是有序的,分别是 : 1,1,2,2,3,3 但是右边的b 不一定有序: 1,2,1,4,3,2
但是在a都为 1 的情况下 b是有序的, 如: a=1时 b =1,2 ; a=2时, b= 1,4; a=3时 ,b=1,2;
如果我们筛选数据的时候, 直接筛选b ,整个就是无序的,需要做全表扫描
如果先a,再b 那么 ,就可以利用树来加快查找速度。
联合索引失效的情形
即不满足最左匹配原则
假如建立如下索引
create index idx_name_age on admin(name,age);
mysql> show index from admin;
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| admin | 0 | PRIMARY | 1 | admin_id | A | 0 | NULL | NULL | | BTREE | | |
| admin | 1 | idx_name_age | 1 | name | A | 0 | NULL | NULL | YES | BTREE | | |
| admin | 1 | idx_name_age | 2 | age | A | 0 | NULL | NULL | YES | BTREE | | |
+-------+------------+--------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
- name和age都走了索引的情况
mysql> explain select * from admin where name='1' and age=2;
+----+-------------+-------+------------+------+---------------+--------------+---------+-------------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------------+------+----------+-------+
| 1 | SIMPLE | admin | NULL | ref | idx_name_age | idx_name_age | 44 | const,const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
- 单查age , 未用到索引
mysql> explain select * from admin where age=2;
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
| 1 | SIMPLE | admin | NULL | ALL | NULL | NULL | NULL | NULL | 1 | 100.00 | Using where |
+----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+-------------+
1 row in set, 1 warning (0.00 sec)
- 单查name, 用到了索引
mysql> explain select * from admin where name='1';
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
| 1 | SIMPLE | admin | NULL | ref | idx_name_age | idx_name_age | 39 | const | 1 | 100.00 | NULL |
+----+-------------+-------+------------+------+---------------+--------------+---------+-------+------+----------+-------+
1 row in set, 1 warning (0.00 sec)
可以看到, 使用了左边字段 name查 ,可以使用索引, 用了右面的age查,无法用到索引
这里只列举这一种索引失效的情况 ,其余还有: 范围值之后失效
- 这种情况下: 由于name使用了范围索引, 导致后面的age 没有走索引
mysql> explain select * from admin where name > '1' and age = 1;
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
| 1 | SIMPLE | admin | NULL | range | idx_name_age | idx_name_age | 39 | NULL | 1 | 100.00 | Using index condition |
+----+-------------+-------+------------+-------+---------------+--------------+---------+------+------+----------+-----------------------+
1 row in set, 1 warning (0.00 sec)
标签:idx,name,原则,admin,age,左匹配,索引,NULL 来源: https://blog.csdn.net/the_power/article/details/112726517