如何让带参数变量的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产生的变量,在查询时很可能导致不走索引,带来严重的性能问题。

另外,本文可能只是表面解决了,深层次的原因依然还是未知,留待后续补充吧。

posted @ 2024-09-23 11:58  jack0424  阅读(9)  评论(0编辑  收藏  举报