首批通过分布式安全可靠测评,为关键业务系统打造
专有云环境中 UPDATE 语句执行效率低下,影响业务运行的原因和解决方法
更新时间:2025-08-08 07:56
问题现象
业务模型特点: 周一到周五表中有插入数据,周六周天不插入数据,每天计算前一天数据 N-1 批量更新,周一 6.30 计算 6.29 日数据,周二 7.1 日计算周一 6.30 日数据,期间 UPDATE 语句执行缓慢。

关键信息
业务模型: 工作日有数据插入,周末无数据插入,每天计算前一天的数据进行批量更新。
pxxxst 表有两个单列索引 INDEX_XXX_DATE(batch_date) INDEX_CD_NO(cd_no)执行计划差异: 周六周天不产生数据,选择
INDEX_XXX_DATE索引是合理的,参数 pxxxst.batch_date = '2025-06-29' 因为不产生数据估行 1 行,实际 0 行,执行非常快。
执行计划差异: 在周一到周五表中有产生业务数据,选择
INDEX_XXX_DATE索引,导致大量回表操作,并且索引列是单列索引,没包含 JOIN 条件 sxxx.asset_no = pxxxst.cd_no 列 cd_no 列没法动态参数下压过滤数据。
虽然周末不会产生业务数据但是也会带入周末当天的参数日期执行。6.28 日有张 sxxx 表累计数据变化超过 10%,到了收集统计信息的时间窗口,带入周末当天的参数日期执行。生成了走 pxxxst(INDEX_XXX_DATE) 的索引被 7.1 日的跑批任务大账号执行导致 UPDATE 语句执行缓慢,影响业务。

问题原因
问题是由业务模型特点决定的,即工作日(周一至周五)表中有数据插入,而周末(周六、周日)无数据插入。由于周末 SQL 执行时无数据插入,携带了参数实际无数据,导致生成的执行计划选择了 INDEX_XXX_DATE 单列索引,这个计划在工作日被 PLAN CACHE 复用,周内数据量大时会导致大量的回表操作,从而严重影响性能。这种场景是常见于券商业务模型,收集统计信息的时间窗口最好在周末不执行避免产生的计划有利于小账号计划被大账号复用,建议 pxxx 表建复合索引(cd_no,batch_date) 也可以覆盖条件列消除回表。
SELECT
sxxx.asset_no
FROM
sxxx
INNER JOIN
pxxxst
ON sxxx.asset_no = pxxxst.cd_no
LEFT JOIN
pxxxt
ON pxxxst.pq_org_code = pxxxt.ptcp_id
WHERE
pxxxst.pq_dt IS NOT NULL
AND sxxx.def_warn_day IS NULL
AND pxxxst.batch_date = '2025-06-29'
AND pxxxst.rq_type != 'PXX1'';
问题的风险及影响
执行效率低下可能导致业务处理延迟,影响用户业务服务。
适用版本
OceanBase 数据库 V4.x 版本。
解决方法与规避方式
建议在 pxxx 表上创建复合索引(cd_no,batch_date)也可以覆盖条件列消除回表。
收集统计信息的时间窗口最好在周末不执行避免产生的计划有利于小账号计划被大账号复用。