本文中联合索引的定义为(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)联合索引想要索引生效,只能使用col1col1,col2col1,col2,col3三种组合;当然,col1,col3组合也可以,但实际上只用到了col1的索引,col3并没有用到!

2 图解

联合索引优化 - 图1

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,需要建立索引,那一般情况下我们的建立索引语句为

  1. 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放在前面。