Mysql造成索引无效的两类总结:
本次摘抄于公众号 58 沈 剑 的 《 架 构 师 之 路 系 列 》 \color{red}{58沈剑的《架构师之路系列》} 58沈剑的《架构师之路系列》
- 第一类:“列类型”与“where值类型”不符,不能命中索引,会导致值全表扫描。
插入测试数据create table table1( cell varchar(3) primary key ) engine=innodb default charset=utf8;
insert into table(cell) values('1'),('2'),('3');
测试语句
explain select * from table1 where cell=1;
explain select * from table1 where cell='1;'
答:
(1)第一条测试语句,where后的值的类型是整数型,与table1中的cell类型不一致;
(2)第二条测试语句,where后的值的类型是字符串,与tabble1中的cell类型一致;
结论:
(1)强制类型转换,不能命中索引,需要全表扫描,即3条记录;
(2)类型相同,命中索引,1条记录;
2.相join的两个表的字符编码不同,不能命中索引,会导致笛卡尔积的循环计算。
create table table2(
cell varchar(3) primary key
) engine=innodb default charset=latin1
插入测试数据
insert into table2(cell) values('1'),('2'),('3')('4')('5');
测试语句
explain select * from table1,table2 where table1.cell = table2.cell
结论:
相join时,连表table1与table2的字符集不同,关联属性是cell,而字符集不同,存储空间就不同,所以table1会遍历出3条记录,tabel1的每一条记录又要遍历table2的所有记录5条,实际进行了笛卡尔积循环计算 ,索引无效。
总结:
- 表列类型,与where的值类型不同;
- join表的字符编码不同