五、联合索引 + 最左匹配原则
(一)为什么使用联合索引?
- 减少开销。创建一个联合索引 (col1,col2,col3),实际相当于建了 (col1),(col1,col2)
,(col1,col2,col3) 三个索引。每多一个索引,都会增加写操作的开销和磁盘空间的开销。对于大量数据的表,使用联合索引会大大减少开销。
- 覆盖索引。对联合索引 (col1,col2,col3),如果有如下 SQL:select col1,col2,col3 from test where col1=1 and col2=2;那么 MySQL 可以直接通过遍历
- 效率高。索引列越多,通过索引筛选出的数据越少。有 1000w 条数据的表。有如下的 SQL:select * from table where col1=1 and col2=2 and col3=3;,假设每个条件可以筛选出 10% 的数据,如果只有单值索引,那么通过索引筛选出$1000w10%=100w$条数据,再回表从 100w 条数据中找到符合 col2=2 and col3=3 的数据,然后再排序,分页;如果是联合索引,通过索引筛选出 $1000w10%*10%*10%=1w$
(二)隐式转换
什么是隐式转换?


运行 select '10'>9;返回 1
运行 select '10'>'9';返回 0
这就是隐式转换规则,对于不同类型的值比较,会把字符串转换为数字
create table db.test(
id BIGINT auto_increment PRIMARY key,
name varchar(30),
create_time TIMESTAMP(6),
update_time TIMESTAMP(6) on UPDATE CURRENT_TIMESTAMP(6)
);
create index idx_name on db.test(name);

select * from test where name = 1 不走索引

select * from test where name = '1' 走索引
等价于 select * from test where name = cast('1' as signed int);
这是因为 MySQL 在遇到字符串和数字比较时,会把字符串转换为数字。
select _ from test where name = 1; 等价于 select _ from test where cast(name as signed int)=1;
(三)对索引使用函数

select * from test where length(name)=2;
对索引使用函数不走索引。
因为索引保存的是索引字段的原始值,而不是经过函数计算后的值。
(四)WHERE 子句中的 OR

因为 OR 的含义是两个条件满足一个即可,所以只有一个条件列是索引列是没意义的
