SELECT xxxxxxxx,xxxxxx FROM `dw_borrow_collection` `t` WHERE (t.user_id=
39064
AND t.repay_time>=
1452441600
AND t.`status` in (
0
,
5
) AND (t.interest+t.capital)>
0
) ORDER BY repay_time LIMIT
4
;
此SQL,repay_time,user_id均有索引,但实际使用中,一次查询需要20s左右,按理说,加了索引,不应该这么慢,最后发现‘repay_time’字段类型是varchar(时间戳的varchar字段转int类型,属另一个话题),但SQL传的值确是int类型的,此时,repayment的索引会失效(隐式转换导致索引失效)。那么,哪些情况会造成mysql的索引失效呢?
我整理了一下,如下:
1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引。
2. like查询以%开头不能使用索引
3. 隐式转换导致索引失效.这一点应当引起重视.也是开发中经常会犯的错误. 如果表的字段定义为varchar,有索引,但传的是int,此时索引失效。反之如果字段类型是int,value是字符串,却并不影响索引。
4. 查询条件使用函数在索引列上,或者对索引列进行运算,运算包括(+,-,*,/,! 等) 错误的例子:select * from test where id-1=9; 正确的例子:select * from test where id=10;
5. 单独引用复合索引里非第一位置的索引列
6. not in ,not exist.
7. B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走
8. 联合索引 is not null 只要在建立的索引列(不分先后)都会走, in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列 都满足is null的时候),或者=一个值; 当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。