为提高效率,提问时请提供以下信息,问题描述清晰可优先响应。
【DM版本】:
【操作系统】:
【CPU】:
【问题描述】*:
请问这个SQL怎么去优化?
第一个SELECT 后面加/+SORT_BUF_SIZE(512)/ 试试
您好
1、是否有准确的统计信息,如果没有尝试使用以下命令收集相关列统计信息
STAT 100 ON RNSSDATA.RS_PLAN_POLICY(PLAN_SEQ);
STAT 100 ON RNSSDATA.RS_WORK_PLAN(PLAN_SEQ);
STAT 100 ON RNSSDATA.RS_WORK_PLAN(IS_VALID);
STAT 100 ON RNSSDATA.RS_WORK_PLAN(BUSINESS_TYPE);
2、参数调整:
SORT_BUF_SIZE = 2048
SORT_BUF_GLOBAL_SIZE = 4090(请根据实际情况调整但必须大于SORT_BUF_SIZE)
3、加并行hint
/+ parallel(6)/ --并行度请根据实际情况调整
并行可能还需要调整PARALLEL_POLICY参数为1或2
SORT_FLAG 这个参数在最新版本上设置为6,可能提高排序在并行中的效率
4、您这个执行计划需要进一步收集信息来分析:
1、表的关联是merge,是否两个表的plan_seq都是表的prime key?(聚簇主键)
2、做一个sql trace看看各个步骤的实际行数,
方法是在disql中执行SF_SET_SESSION_PARA_VALUE('MONITOR_SQL_EXEC',1);
然后再执行set autotrace trace(如果结果集过大刷不完,就set autotrace traceonly)
3、rpp表的policy no有多少个distinct值?就是说最终的结果集有多少行?t视图有多少行?如果distinct值不多(组数大幅度少于总行数),考虑先distinct把驱动row source 做小,然后再用主键或者rowid绕回来查最大的一行补字段。
保持沟通。
该SQL语句的优化可以从以下几个方面考虑:
索引优化
建议在RS_WORK_PLAN表上建立复合索引(PLAN_SEQ, IS_VALID, BUSINESS_TYPE),这样能加速连接条件和过滤条件的匹配效率。同时,如果UPDATED_DATE字段是排序关键字段,可为RS_WORK_PLAN表的UPDATED_DATE字段建立降序索引(例如:CREATE INDEX IDX_RWP_UPDATE_DESC ON RS_WORK_PLAN(UPDATED_DATE DESC)),避免窗口函数中频繁的全排序操作。
数据量裁剪
检查子查询中RS_WORK_PLAN表的过滤条件IS_VALID='Y'和BUSINESS_TYPE='WP'是否能通过分区表或预过滤机制缩小数据集。如果业务允许,可尝试将历史冷数据归档,减少参与计算的数据量。
执行计划分析
通过达梦的EXPLAIN功能查看执行计划,重点关注是否出现全表扫描(如BLKUP2或SSEK2扫描范围过大)、排序耗时(如SORT节点代价高)等问题。若发现连接操作未走索引,可通过HINT强制指定索引(例如:/*+ INDEX(rwp IDX_RWP_MAIN) */)。
窗口函数改写
如果POLICY_NO和PAY_TIMES组合的唯一性较高,可尝试将窗口函数改为关联子查询+TOP 1的方式(需测试效果)。例如:
sql
SELECT (
SELECT TOP 1 rwp.UPDATED_DATE
FROM RNSSDATA.RS_WORK_PLAN rwp
WHERE rwp.PLAN_SEQ = rpp.PLAN_SEQ
AND rwp.IS_VALID = 'Y'
AND rwp.BUSINESS_TYPE = 'WP'
ORDER BY rwp.UPDATED_DATE DESC
) AS last_updated
FROM RNSSDATA.RS_PLAN_POLICY rpp
5. 临时表物化
对于大数据量场景,可尝试将子查询结果物化为临时表并添加索引:
sql
CREATE GLOBAL TEMPORARY TABLE TMP_PLAN AS
SELECT rpp.POLICY_NO, rpp.PAY_TIMES, rwp.*
FROM RNSSDATA.RS_PLAN_POLICY rpp
INNER JOIN RNSSDATA.RS_WORK_PLAN rwp ON rwp.PLAN_SEQ = rpp.PLAN_SEQ
WHERE rwp.IS_VALID = 'Y' AND rwp.BUSINESS_TYPE = 'WP';
-- 添加索引
CREATE INDEX IDX_TMP_POLICY ON TMP_PLAN(POLICY_NO, PAY_TIMES, UPDATED_DATE DESC);
验证建议
建议先通过EXPLAIN确认索引是否生效,再通过达梦的性能监控工具(如v$sessions、v$sql_history)观察执行耗时和资源消耗。若数据分布倾斜严重(例如某些POLICY_NO对应的数据量极大),可能需要结合业务特点设计更精细的分区策略。
主要原因是RWP和RPP全表扫描,数据没有过滤性,可以尝试下business_type,is_valid,plan_seq 组合索引看看能不能消除RWP表的全表扫描,但如果过滤性不好,效果应该也不好