如何让带参数变量的mysql查询走索引?
1,问题的提出
mysql 5.7的数据库,jx_performance表含索引idx_performance。该索引关联两个字段:`date`, `user_id`。
在运行sql语句时发现,如果where条件采用参数变量,则查询不走索引。
图1,带参数变量查询
图2,采用字符串常数查询
上图1和图2,实际上查询条件一样,因为查询前采用了如下赋值方式:
set @LZJ_id='5ff67822d08e51e7609d073a'; set @lastMonth='2024-08';
因此二者返回的数据也一样,但是采用带参数的查询(图1)明显耗时太长。
2,原因分析
为什么如此奇怪?明明查询条件一样,只是写法不一样,查询耗时就能相差几千倍?
采用explain分析语句如下:
上述对比发现,采用参数变量的查询,没有走索引,虽然相关查询字段都在索引中。
为什么mysql会采用这种策略呢?令人费解。
网上查询了些说法,大致是有计算、数据类型不一致等等,我对比发现不存在这些问题。
也有说加强制索引的,尝试了发现无效。如下图:
3,解决方案
山重水复疑无路,柳暗花明又一村。
经过思考,我觉得问题可能还是出在 变量参数的类型上,我在set 变量前,未声明变量类型,可能导致查询优化器无法使用索引。
有此怀疑,立即将参数变量的赋值改写为如下:
declare lastMonth varchar(50); declare LZJ_id varchar(50); set LZJ_id='5ff67822d08e51e7609d073a'; set lastMonth='2024-08';
结果表明,带参数变量的查询也能走索引了!查询速度大大提高,问题得到解决。
4,总结
mysql中使用set语句给变量赋值非常方便,因此经常不写declare语句。
但是,直接 set产生的变量,在查询时很可能导致不走索引,带来严重的性能问题。
另外,本文可能只是表面解决了,深层次的原因依然还是未知,留待后续补充吧。