实战 | 搞定“in”值过多导致的慢SQL问题,你可以这样做……

在最近的某财政项目中,达梦的性能监控工具定位了一些慢SQL问题。针对这些问题,达梦专家和应用厂商一起采用了创建索引、优化视图、引进临时表等方法进行优化。

下面我们将展示一个典型问题——由“in”值过多导致的慢SQL,让我们一起来看看,高手是如何用达梦特有的事务级临时表解决的。

问题详情


在前段时间的项目中,出现了一个很典型的查询优化问题。在此跟大家分享问题分析及解决方法。

此例中SQL文本大小达1.8MB,如下:

select
        count(1)
from
        V_XXXXXXXXXXXXXX t
where
                                        C1= '235432'
                                    and C2= '345436'
    and
        (
                C3  = 'SADFDSGADFDSAFDSAFSAD'
             or C3 is null
        )
    and
        (
          id in ('ERTRTEWEB4DF2BE413523615EFDBA', 
              'ERTETRET2A7C44AE83EFEC5DD4169FA2', 'FF053E459ERTRETRETR755D70B6C1712', 
              '057ERWTETETRETRETRRRD8738ED5D886', '0518C9DERWTRETRETREE63B5346B38B3', 
              '3E50D3EF6ERTRERTRTREE6920014CD55', '421FA8BERTERTEWTEWRTREA1181A059A', 
              '31E2F34EWRTREWRTE31F72CA0563E4C9', '356EWRTREWTREWGFD1BE5DB4A4A39BEE', 
                 ................此处省略数万行
              '8BEE2AERTEWTR70885B6421166C3A6C5', '296E705ERTRETWHG456196D973439599')
        )

这是一个多表连接的比较复杂的视图,SQL的过滤条件里id列 “in” 了几万个常量(红框部分)。这条语句第一次执行需要12秒,第二次执行时间为毫秒级。

原因分析


上述两次执行时间的差别,说明该语句执行时间主要消耗在SQL硬解析上。由于项目中相关功能的并发量较大,这条慢SQL引发了严重的性能问题。

这个问题比较普遍。主要原因是开发人员图简单,对“in”列表里常量的个数没有评估。常量动辄数万,甚至数十万,这种SQL在并发量较大的情况下就是灾难。

优化思路


1. 创建一个事务级的临时表

CREATE GLOBAL TEMPORARY TABLE TMP_INLIST
(
    ID VARCHAR(100)
 
) ON COMMIT DELETE ROWS;

2. 将需要参与过滤的常量值插入临时表

--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首次执行时间由十几秒降至毫秒级

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值