条件中in值过多导致的慢SQL问题
在前段时间的项目中,出现了一个很典型的查询优化问题。在此跟大家分享问题分析及解决方法。
此例中SQL文本大小达1.8MB,如下:
这是一个多表连接的比较复杂的视图,SQL的过滤条件里id列 “in” 了几万个常量(红框部分)。这条语句第一次执行需要12秒,第二次执行时间为毫秒级。
原因分析
上述两次执行时间的差别,说明该语句执行时间主要消耗在SQL硬解析上。由于项目中相关功能的并发量较大,这条慢SQL引发了严重的性能问题。
这个问题比较普遍。主要原因是开发人员图简单,对“in”列表里常量的个数没有评估。常量动辄数万,甚至数十万,这种SQL在并发量较大的情况下就是灾难。
优化思路
1. 创建一个事务级的临时表
CREATE GLOBAL TEMPORARY TABLE TMP_INLIST
(
ID VARCHAR(100)
) ON COMMIT DELETE ROWS;
--addBatch()批量绑定参数
INSERT INTO TMP_INLIST VALUES(?);
3. 改写SQL语句
select
count(1)
from
V_XXXXXXXXXXXXXX t
where
C1= '235432'
and C2= '345436'
and
(
C3 = 'SADFDSGADFDSAFDSAFSAD'
or C3 is null
)
and
(
id in (select id from TMP_INLIST)
);
解决效果
按上述优化思路处理后,不管“in”列表里面有多少个常量,SQL解析的代价都是一样的,性能问题得到解决。在本例中,此条SQL首次执行时间由十几秒降至毫秒级。
分类:
达梦数据库知识文档
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署