问题描述:用户表有一个手机号字段,该字段定义为char类型,并且在改字段上建立了索引。系统升级涉及到手机号字段的处理和查询,处理完后查询条件中原本为string类型的手机号变成了int的手机号,导致不能使用索引,从而导致了慢查询。
解决方法:传入查询语句中手机号转换为string类型。
生成int查询条件原因及排查过程:拿到上游给的加密手机号后进行了解密处理,处理结果为string类型,但直接用有问题,于是随手写了一个intval()将string类型的值转换成了int类型。问题就出在这里,不应该做int类型的转换,而应该用trim()方法移除字符串两侧的空白字符或预定义字符。为什么解密后得到的字符串两侧会有预定义字符呢?是因为加解密算法一般会做\0之类的填充,来达到和密钥成比例的长度,再进行计算。
其他心得:php中var_dump能够将字符串类型及内容完整打印,所有排查问题尽量多用var_dump,少用系统封装的日志打印函数(打印出来的字符串已经进行了处理)。
------------------------------------------------------
造成索引失效的集中原因:http://linmomo02.iteye.com/blog/1171069
1,<>
2,单独的>,<,(有时会用到,有时不会)
3,like "%_" 百分号在前.
4,表没分析.
5,单独引用复合索引里非第一位置的索引列.
6,字符型字段为数字时在where条件里不添加引号. -------命中的情形
7,对索引列进行运算.需要建立函数索引.
8,not in ,not exist.
9,当变量采用的是times变量,而表的字段采用的是date变量时.或相反情况。
10, 索引失效。
11,基于cost成本分析(oracle因为走全表成本会更小):查询小表,或者返回值大概在10%以上
12,有时都考虑到了 但就是不走索引,drop了从建试试在
13,B-tree索引 is null不会走,is not null会走,位图索引 is null,is not null 都会走
14,联合索引 is not null 只要在建立的索引列(不分先后)都会走,
in null时 必须要和建立索引第一列一起使用,当建立索引第一位置条件是is null 时,其他建立索引的列可以是is null(但必须在所有列都满足is null的时候),或者=一个值;
当建立索引的第一位置是=一个值时,其他索引列可以是任何情况(包括is null =一个值),以上两种情况索引都会走。其他情况不会走。