联合索引最左匹配原则

建表语句:

CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(30) DEFAULT NULL COMMENT '名称',
  `sex` varchar(1) DEFAULT NULL COMMENT '性别',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `card_no` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_name_sex_card_no` (`name`,`sex`,`card_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8;

设置联合索引:

顺序为(`name`,`sex`,`card_no`)分别用a,b,c代表。

-- name, sex, card_no
EXPLAIN select * from user where name = '1'; -- a ref
EXPLAIN select * from user where name = '1' and sex = '1'; -- ab ref
EXPLAIN select * from user where name = '1' and sex = '1' and card_no = '1'; -- abc ref
EXPLAIN select * from user where card_no = '1' and sex = '1' and name = '1'; -- cba ref
EXPLAIN select * from user where name = '1' and card_no = '1'; -- ac ref
EXPLAIN select * from user where card_no = '1' and name = '1'; -- ca ref
EXPLAIN select * from user where sex = '1' and card_no = '1'; -- bc ALL
EXPLAIN select * from user where sex = '1'; -- b ALL
EXPLAIN select * from user where card_no = '1'; -- c ALL
-- 最左匹配原则
-- a必须得有
-- 覆盖索引
EXPLAIN select name,sex,card_no from user where name = '1' and sex = '1' and card_no = '1';

依次执行结果:

a

 ab

 

abc

cba

 ac

 ca

 

 bc

 

 b

 c

 

 覆盖索引:即查询的列被索引覆盖。例如abc,查询的字段是abc的列即覆盖索引。

结论:

以a,b,c顺序建立联合索引:

a 使用a索引。type=ref,key_len=93。

ab使用ab索引。type=ref,key_len=99。

abc使用abc联合索引。type=ref,key_len=192。

ac使用a索引。type=ref,key_len=93。

b,c,bc未走索引。type=ALL。

覆盖索引。type=ref。

以上abc的顺序在sql中可随意,mysql执行时会优化顺序,例如cba会优化为abc。

要想使得索引生效索引a必须存在。即最左匹配。

索引原理请参考二叉树,B树,B+树。是一个演变的过程。

参考:

https://blog.csdn.net/weixin_47162914/article/details/123793589?spm=1001.2014.3001.5506

 

posted @ 2022-11-29 19:41  super超人  阅读(246)  评论(0编辑  收藏  举报