【 使用环境 】生产环境
【 OB or 其他组件 】OB
【 使用版本 】4.2.1.10
【问题描述】清晰明确描述问题
【复现路径】DISTINCT t.*导致执行计划变化且比DISTINCT t.id指定列名慢几十倍
【附件及日志】
【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!
执行慢执行计划.txt (5.9 KB)
执行快执行计划.txt (6.8 KB)
【 使用环境 】生产环境
【 OB or 其他组件 】OB
【 使用版本 】4.2.1.10
【问题描述】清晰明确描述问题
【复现路径】DISTINCT t.*导致执行计划变化且比DISTINCT t.id指定列名慢几十倍
【附件及日志】
【备注】基于 LLM 和开源文档 RAG 的论坛小助手已开放测试,在发帖时输入 [@论坛小助手] 即可召唤小助手,欢迎试用!
执行慢执行计划.txt (5.9 KB)
执行快执行计划.txt (6.8 KB)
根因分析场景: SQL性能问题
根因分析命令: obdiag rca run --scene=sql_performance_issue
日志采集场景: SQL性能问题
日志采集命令: obdiag gather scene run --scene=observer.perf_sql --env “{db_connect=’-h127.0.0.1 -P2881 -utest@test -p****** -Dtest’, trace_id=‘Yxx’}”
推荐使用 obdiag 工具进行根因分析和日志采集,以便确认问题所在。上述命令将帮助我们收集 SQL 执行相关的性能数据,并分析 DISTINCT t.* 导致执行计划变化且性能下降的原因。
麻烦您提供一些信息以便我们更好地帮助您:
EXPLAIN
命令获取)。trace_id
或者具体的执行时间范围,以便我们在日志中定位相关 SQL 的执行记录?附上敏捷诊断工具 obdiag 使用帮助链接
执行计划没有办法看 看着像是乱码了么?
1、执行快和慢的explain extended sql --保存在文本里 不要脱敏
2、
日志采集场景: SQL性能问题
日志采集命令: obdiag gather scene run --scene=observer.perf_sql --env “{db_connect=’-h127.0.0.1 -P2881 -utest@test -p****** -Dtest’, trace_id=‘Yxx’}”
–根据时间和执行语句查询trace_id
select query_sql,svr_ip,TRACE_ID,client_ip,TENANT_NAME,user_name,DB_NAME,ELAPSED_TIME,RET_CODE,FROM_UNIXTIME(ROUND(REQUEST_TIME/1000/1000),’%Y-%m-%d %H:%i:%S’) from GV$OB_SQL_AUDIT
WHERE REQUEST_TIME>=‘2024-04-05 14:34:00’ and lower(query_sql) like ‘%select%’;
根据您提供的执行计划文件内容,我们可以对比两种 SQL 的执行计划差异,并分析性能问题的原因。以下是详细分析和建议:
HASH JOIN
和 TABLE FULL SCAN
。SUBPLAN SCAN
) 和分组操作 (HASH GROUP BY
)。TABLE FULL SCAN
和 HASH GROUP BY
的开销较高。dsp_assets_data_approve_log
和表 a
进行了全表扫描。HASH GROUP BY
去重。NESTED-LOOP OUTER JOIN
和 MERGE GROUP BY
。SUBPLAN SCAN
) 和去重操作 (HASH DISTINCT
) 更加高效。id
列进行去重,避免了对所有列的处理。MERGE GROUP BY
和 NESTED-LOOP JOIN
的开销较低。DISTINCT t.*
需要对所有列进行去重,涉及更多的数据处理和内存消耗。DISTINCT t.id
只对单列进行去重,计算量显著减少。DISTINCT t.*
导致优化器选择了更复杂的执行计划(如 HASH JOIN
和 TABLE FULL SCAN
),增加了 I/O 和 CPU 开销。DISTINCT t.id
的执行计划更加简单,使用了更高效的 NESTED-LOOP JOIN
和 MERGE GROUP BY
。DISTINCT t.*
的开销会显著增加。id
列,直接使用 DISTINCT t.id
。id
,再关联其他列。例如:SELECT t.*
FROM your_table t
WHERE t.id IN (
SELECT DISTINCT id
FROM your_table
);
id
列上创建唯一索引或普通索引,加速去重操作。CREATE INDEX idx_id ON your_table (id);
SELECT *
,仅选择必要的列。GROUP BY
替代 DISTINCT
。例如:SELECT id, col1, col2
FROM your_table
GROUP BY id, col1, col2;
EXPLAIN
分析执行计划,确保优化器选择了最优路径。obdiag
工具收集更多性能数据,定位具体瓶颈。例如:obdiag rca run --scene=sql_performance_issue
DISTINCT t.*
比 DISTINCT t.id
慢的主要原因是前者需要对所有列进行去重,导致执行计划复杂化和计算量增加。建议根据实际需求减少列选择,并通过索引优化和 SQL 调整提升性能。
详情请参考:
(小助手的答复已结束,如未能解决您的问题,请继续提问并等待其他同学的回复,谢谢!)
obdiag version: 3.2.0
[ERROR] rca run Exception: rca_scene :sql_performance_issue is not exist
没有这个命令 你按照这命令来
那个快的语句 也用obdiag收集一下
有报这错
[WARN] failed to find sql_plan_monitor data, please add hint /+ monitor/ to your SQL before executing it
重新加一下hint/+ monitor / 在执行一下快的语句 再重新收集一下