联合索引 又叫复合索引,是在表中两个或两个以上的列上创建的索引。
利用索引中的附加列,可以缩小检索的段池范围,更快地搜索到数据。

创建联合索引语法:

create index idx_c1_c2 on table_name (c1,c2);

联合索引的使用过程中,必须要满足最左前缀原则。一般把选择性高的列放在前面。

如果查询语句只使用索引中的一部分,则必须从最左侧开始。

以下查询可以使用到索引:

select * from t where c1=某值;

# 交换顺序也可以使用到
select * from t where c2=某值 and c1=某值;

# 包含in也可以使用
select * from t where c1=某值 and c2 in(某值,某值);

# 排序使用的是 Using filesort
select * from t order by c1,c2;

select * from t where c1=某值 order by c2;

联合索引中 条件中的 字段先后顺序没有关系,无需和索引中字段顺序一致。

如只使用联合索引的一部分,只要满足从最左侧开始,条件中字段先后顺序也没关系。

如下示例:

索引是:undex_code:data_code, data_type, status

EXPLAIN SELECT * FROM rd_data_dict WHERE data_code = '19939124530151424' AND data_type = '19938655992840192' AND `status` = '1';

-- 这里可以使用到索引
EXPLAIN SELECT * FROM rd_data_dict WHERE `status` = '1' AND data_type = '19938655992840192' AND data_code = '19939124530151424';

-- 这里可以使用到索引
EXPLAIN SELECT * FROM rd_data_dict WHERE `status` = '1' AND data_type = '19938655992840192' AND data_code IN('19939124530151424','19939168029278208','19939324216770560');

-- 这里无法使用索引
EXPLAIN SELECT * FROM rd_data_dict WHERE `status` = '1';

-- 这里无法使用索引
EXPLAIN SELECT * FROM rd_data_dict WHERE `status` = '1' AND data_type = '19938655992840192';

-- 这里可以使用到索引
EXPLAIN SELECT * FROM rd_data_dict WHERE data_type = '19938655992840192' AND data_code IN('19939124530151424','19939168029278208','19939324216770560');

-- 这里可以使用到索引
EXPLAIN SELECT * FROM rd_data_dict WHERE data_code IN('19939124530151424','19939168029278208','19939324216770560');

-- 这里可以使用到索引
EXPLAIN SELECT * FROM rd_data_dict WHERE `status` = '1' AND data_code IN('19939124530151424','19939168029278208','19939324216770560');

以下情况无法使用到索引:

select * from t where c2=某值;
select * from t where c2=某值 order by c1;

还有一种特殊的情况:

select * from t where c1=某值 or c2=某值;

虽然 c1 字段在前,但是这种情况是不能使用到索引的。

这种情况可以在 c1、c2 字段上面建两个单列索引。

注:尽量在生产环境中,让程序端多做一些判断,不要让数据库做各种运算。尽量避免在SOL语句中出现 or 关键字。多列中可以考虑使用 union。

作者:admin  创建时间:2023-01-13 11:40
最后编辑:admin  更新时间:2023-02-02 14:25