问题描述
在一次压测中发现,代码中有一步查询mysql的时间过长,甚至达到了几十秒。该查询操作本身很简单,就是一个按主键查询,mapper中语句如下:
<select id="select" parameterType="java.lang.Integer">
select * from tb
where XX = #{XX,jdbcType=INTEGER}
</select>
原因分析:
首先检查了数据库,该主键是加了索引的。而且库内的数据量不算太大。
之后,在压测过程中,手动执行sql语句,发现耗时不大。一度怀疑是程序连接池问题。
最后突然发现,手动执行的sql是:
select * from tb where XX = "XX"
加了引号,也就代表是按字符串类型去查询的,而程序是按照数字类型查询的。
再次检查建表语句,发现该值是字符串类型,所以只有按字符串类型查询,索引才会生效。按数字类型查询,索引不生效,所以耗时很大。
解决方案:
知道了问题所在,修改就很简单了,把mapper中的类型改为VARCHAR:
<select id="select" parameterType="java.lang.String">
select * from tb
where XX = #{XX,jdbcType=VARCHAR}
</select>
索引生效,性能百倍提升!
经验总结:
顺便学习一下索引不生效的几种原因,以后工作中要多多注意。