OB_MYSQL UPDATE 优化案例

在工单系统上看到有一条SQL问题还没解决,直接联系这位同学看看是否需要帮忙。

慢SQL:

复制代码
UPDATE  A
SET CORPORATION_NAME = (
    SELECT DISTINCT CORPORATION_NAME
    FROM (
        SELECT CONTRACT_NO, 
               COOP_SERVICE_TYPE, 
               CORPORATION_NAME, 
               PROJECT_NAME, 
               ROW_NUMBER() OVER (PARTITION BY CONTRACT_NO, COOP_SERVICE_TYPE ) AS SEQ
        FROM O_PLIS_PROC B
        WHERE B.BDHA_TX_DATE='2024-06-10' AND A.LM_CT1_NO = B.CONTRACT_NO
    ) B
    WHERE B.COOP_SERVICE_TYPE='01' AND B.SEQ = 1
)
WHERE LM_CT1_NO IN (
    SELECT  CONTRACT_NO
    FROM O_PLIS_PROC C
    WHERE C.CONTRACT_NO=A.LM_CT1_NO
    AND C.COOP_SERVICE_TYPE='01'
    AND C.BDHA_TX_DATE='2024-06-10'
);

执行计划:

上面sql 跑超时都跑不出结果,估计要执行非常长时间。

这条sql in 后面关联返回107911行数据,update set ... 可以理解成标量子查询,返回1107911数据相当于 update set 标量子查询也要执行107911次。

标量子查询最重要的是要走对索引,然而这个sql计划根本没走索引,这位同学的问题也是如何通过改写来消除标量子查询,很明显这个思路是错误的。

添加合适的索引:

复制代码
CREATE INDEX TEST ON O_PLIS_PROC(
  BDHA_TX_DATE,
  COOP_SERVICE_TYPE,
  CONTRACT_NO,
  COOP_SERVICE_TYPE,
  CORPORATION_NAME);

很明显,创建索引以后计划显示能用上索引,sql整体5秒能执行完成。

再提供个相同逻辑的等价改写方案:

复制代码
WITH O_PLIS_PROC as (
    SELECT 
           CONTRACT_NO,
           COOP_SERVICE_TYPE,
           CORPORATION_NAME
     FROM O_PLIS_PROC 
     WHERE BDHA_TX_DATE='2024-06-10' AND COOP_SERVICE_TYPE='01'
)
UPDATE A
SET CORPORATION_NAME = (
    SELECT  CORPORATION_NAME 
        FROM O_PLIS_PROC B 
    WHERE A.LM_CT1_NO = B.CONTRACT_NO  GROUP BY CONTRACT_NO, COOP_SERVICE_TYPE LIMIT 1 ) 
WHERE LM_CT1_NO IN (
    SELECT  CONTRACT_NO
    FROM O_PLIS_PROC C
    WHERE C.CONTRACT_NO=A.LM_CT1_NO
);

改写后的sql 5秒能跑出结果,和原来逻辑一样,提升不大。

遇到性能慢的sql语句,不要一上来就想着等价改写,先通过索引进行优化,合理的索引能解决90%的性能问题。

如果索引都解决不了的情况下,才去尝试使用等价改写来进行优化sql,一般来说等价改写能解决剩下5%的问题。

如果连等价改写都解决不了剩下的5%的性能问题话,就要尝试改业务,或者改数据库技术栈来解决问题了,这种通常来说成本会非常高。

相关推荐
憧憬成为web高手11 小时前
皮卡丘靶场速通--sql 2
数据库·sql·mybatis
yio_yin17 小时前
Spring事务管理(数据一致性)
数据库·sql·spring
Csvn19 小时前
📊 SQL 入门 Day 9:CTE(公用表表达式)— 让 SQL 像写代码一样优雅
后端·sql
虹科网络安全20 小时前
艾体宝新闻|从 SQL 注入到服务器接管:CVE-2026-57517 暴露 Web 管理面板的供应链与安全编码风险
服务器·前端·sql
Databend21 小时前
用 QUALIFY 写出更清晰的窗口函数 SQL
数据库·sql·数据分析
难寻安逸1 天前
DVWA-使用sqlmap 进行sql注入过程
数据库·sql·网络安全
Csvn1 天前
📊 SQL 入门 Day 8:集合操作 — 用 SQL 做数学里的"并交差"
后端·sql
Irene19912 天前
大数据开发的常见实践:把 SQL 直接写在 Shell 脚本里 ER图 数据血缘
sql·数据血缘·er
川石课堂软件测试2 天前
安全测试|常见SQL注入攻击方式、实例及预防
服务器·数据库·sql·功能测试·测试工具·安全·单元测试
qq_366086222 天前
sql 查询中关于 null 值判断的问题
数据库·sql