mysql索引失效场景总结

前言

mysql的调优方面包括 表结构优化、索引优化、sql语句优化、分表分库优化等多个维度,本篇重点总结的是索引失效的场景和原因。


写博客是自己对知识梳理,目前是写给自己看,算是自己学习后的作业,也是为了养成一个良好的习惯。

一、不满足最左匹配原则

先复习一下最左匹配原则:
	1. 创建一个联合索引 index(a,b,c) 则相对于创建了 idx_a(a)idx_a_b(a,b)idx_a_b_c(a,b,c) 3个索引。
	-------------------------------------------------------
	select * from table where a='a' and c='c';
	这种都之会走 idx_a索引,而 字段 c则不会走索引。
	-------------------------------------------------------
	select * from table where b='b' and c='c';
	这种会走全表扫描,index索引失效。
	-------------------------------------------------------

	2. 联合索引在遇到范围查询之后字段的索引就会失效。
	-------------------------------------------------------
	select * from table where a like 'a%' and b='b';
	这种会走idx_a索引的范围检索,字段b不会走索引。
	-------------------------------------------------------

二、频繁回表

	先来分析一下以下sql在mysql下是如何执行的:
	select * from table where age > 20 ; --其中 字段age 创建索引 
	会先在索引age字段的b+tree上查询到关于符合条件的id,然后在聚簇索引上通过id回表查询到完整数据。
	则select * 一定会有回表操作,当查询的结果超过了总数一半以上且总数很多时,这个时候回表开销比全表扫描的开销还大,则mysql优化器会它走全表扫描,即索引失效了。

三、索引列上有计算

	举例:select * from t_user where age+1=10;
	这种索引会直接失效。

四、索引列上有函数

	举例:select * from user where SUBSTR(height,1,2)=17;
	这种索引会直接失效。

五、字段类型不同

	举例:select * from user where type = '5';
	type是整数类型,查询时用字符串,mysql会做隐式转换,索引会直接失效。
	-------------------------------------------------------
	举例:select oi.*,ui.name from order_info oi left join user_info ui on oi.user_id = ui.id;
	其中order_info的user_id是字符串类型,user_info的id是整数类型,即便order_info的user_id创建索引也会由于字段类型不同而做隐式转换,索引会失效。

六、列对比

	举例:select * from user where id=height;
	列对比索引会直接失效。

七、常见索引失效

	诸如索引列 使用了 not in、 like ‘%x’ 、or 都会索引失效

你可能感兴趣的:(mysql,数据库,java)