本文中联合索引的定义为(MySQL):
ALTER TABLE table_name
ADD INDEX (col1
,col2
,col3
);
一、联合索引的优点
若多个一条SQL,需要多个用到两个条件
SELECT * FROM user_info
WHERE username=’XX’,password=’XXXXXX’;
当索引在检索 password
字段的时候,数据量大大缩小,索引的命中率减小,增大了索引的效率。
联合索引的索引体积比单独索引的体积要小,而且只是一个索引树,相比单独列的索引要更加的节省时间复杂度和空间复杂度
二、联合索引命中的本质(最左匹配的理解)
1 定义
当创建(col1
,col2
,col3
)联合索引时,相当于创建了(col
)单列索引,(clo1
,clo2
)联合索引以及(col1
,col2
,col3
)联合索引想要索引生效,只能使用col1
和col1
,col2
和col1
,col2
,col3
三种组合;当然,col1
,col3
组合也可以,但实际上只用到了col1
的索引,col3
并没有用到!
2 图解
3 通俗理解
联合索引相当于一个按照姓氏——名字
的一个电话簿,只能先确定姓氏才可以命中索引,下列可以正确命中联合索引的语句( =
和IN
直接的字段都可以乱序,MySQL的查询优化器可以优化成索引识别的形式)
— 只命中 col1,col2
SELECT * FROM table_name
WHERE col1
=’XX’;
— 命中col1,col2。col1,col2的顺序可以颠倒
SELECT FROM table_name
WHERE clo1
=’XX’,clo2
=’XXX’;
SELECT FROM table_name
WHERE clo2
=’XXX’, clo1
=’XX’;
— 命中col1,col2,col3,同理,三个列的顺可以颠倒
SELECT FROM table_name
WHERE col1
=’X’,col2
=’XX’,col3
=’XXX’;
SELECT FROM table_name
WHERE col1
=’X’,col3
=’XX’,col2
=’XXX’;
SELECT * FROM table_name
WHERE col2
=’X’,col3
=’XX’,col1
=’XXX’;
4 索引顺序问题
如果我们已经确定了,需要在col1
,col2
,col3
三列上建立联合索引,那么如何安排索引的顺序?怎么写这个索引创建语句呢?
排列原则:能够快速筛选出少量数据的索引排在前面,例如订单表(order)有两个列 status,date,需要建立索引,那一般情况下我们的建立索引语句为
alter table order create index inx_s_d (`date`,`status`)
而不是:
alter table order create index inx_s_d (`status`,`date`)
我们把日期date放在前面,因为一个大表中status的值往往只有几种,例如status=1 的数据可能就占了表的1/4,而日期能够快速拿到较少的数据,因此我们把日期date放在前面。