首页   快速返回

联合索引与最左匹配原则     所属分类 mysql
多列索引(联合索引) 最左匹配原则


2列的联合索引(col1,col2), 建立两个索引(col1)  (col1,col2)
3列的联合索引(col1,col2,col3),建立三个索引(col1) (col1,col2) (col1,col2,col3)

复合索引的结构与电话簿类似,人名由姓和名构成,首先按姓氏对进行排序,然后按名字对有相同姓氏的人进行排序。

如果知道姓,电话簿将非常有用;
如果知道姓和名,电话簿则更为有用,
但如果只知道名不知道姓,电话簿将没有用处。



覆盖索引
联合索引(a,b,c)
select a,b,c from table where a=1 and b = 1
直接通过遍历索引取得数据,无需回表,减少了很多io操作


创建联合索引时列的选择原则

经常用的列优先(最左匹配原则)
离散度高的列优先(离散度高原则)
宽度小的列优先(最少空间原则)

列的离散性计算
count(distinct col)/ count(col)
id列一共9项都不重复 9/9 = 1
性别列一共9项只有(男或者女)两列 2/9 约等于0.2
离散性越高选择性越大

CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64),
  `sex` varchar(8) ,
  `city` varchar(32) ,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `name`(`name`, `sex`, `city`) USING BTREE
)
EXPLAIN select * from `user` where sex='';

无法命中联合索引,不符合最左原则,没有命中(a) (ab) (abc) 这三种组合

+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
| id | select_type | table | partitions | type  | possible_keys | key  | key_len | ref  | rows | filtered | Extra                    |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
|  1 | SIMPLE      | user  | NULL       | index | NULL          | name | xxx     | NULL |    3 |    33.33 | Using where; Using index |
+----+-------------+-------+------------+-------+---------------+------+---------+------+------+----------+--------------------------+
1 row in set (0.02 sec)

执行计划,只有possible_keys有值的情况下才命中索引


where条件的顺序是否会影响索引的命中
索引组合 (ab) ,where语句写成(ba)
mysql5.7测试 可以命中索引

B+Tree
非叶子节点不存储data,只存储索引key
只有叶子节点才存储data
叶子节点增加指向相邻叶子节点的指针 ,方便顺序访问

上一篇     下一篇
redis使用zset保留最近的数据

B+树 与 B树 索引

B树与红黑树,为什么数据库使用B树索引

Jedis客户端分片机制

一致性hash与treemap

MapReduce和Tez比较