【 使用环境 】测试环境
【 OB or 其他组件 】ob
【 使用版本 】4218
【问题描述】跑批期间发现更新sql cpu占比太高,走全表扫描
【附件及日志】
sql语句:
update BS_GL_POST set STAT_CD=‘P’ , TRANS_TM = ‘2024-11-10 18:20:36.000892’
WHERE 1 = 1 AND BLORG_NO = ‘0611’ AND INDEX_NO BETWEEN ‘102030111’ and ‘102032110’
AND ( PTXSP_MID_ENTRY_FLAG != ‘Y’ OR PTXSP_MID_ENTRY_FLAG IS NULL ) AND STAT_CD=‘O’
AND POST_DT < ‘2024-06-18’ AND VIRTUAL_FLAG=‘N’;
EXPLAIN EXTENDED UPDATE BS_GL_POST
SET STAT_CD = 'P', TRANS_TM = '2024-11-10 18:20:36.000892'
WHERE BLORG_NO = '0611'
AND INDEX_NO BETWEEN '102030111' AND '102032110'
AND (PTXSP_MID_ENTRY_FLAG != 'Y' OR PTXSP_MID_ENTRY_FLAG IS NULL)
AND STAT_CD = 'O'
AND POST_DT < '2024-06-18'
AND VIRTUAL_FLAG = 'N';
优化索引:
确保索引的列顺序与查询条件匹配。索引的前导列应该出现在 WHERE 子句的前面。
例如,如果 BLORG_NO 和 INDEX_NO 经常一起使用,可以创建复合索引:
CREATE INDEX idx_bs_gl_post_blorg_no_index_no ON BS_GL_POST (BLORG_NO, INDEX_NO);
CREATE INDEX idx_bs_gl_post_blorg_no_index_no ON BS_GL_POST (BLORG_NO, INDEX_NO);
EXPLAIN EXTENDED UPDATE BS_GL_POST
SET STAT_CD = 'P', TRANS_TM = '2024-11-10 18:20:36.000892'
WHERE BLORG_NO = '0611'
AND INDEX_NO BETWEEN '102030111' AND '102032110'
AND (PTXSP_MID_ENTRY_FLAG != 'Y' OR PTXSP_MID_ENTRY_FLAG IS NULL)
AND STAT_CD = 'O'
AND POST_DT < '2024-06-18'
AND VIRTUAL_FLAG = 'N';
总结
通过确保 UPDATE 语句使用主键索引或合适的复合索引,可以显著提高查询性能,减少 CPU 占用。同时,定期收集统计信息也有助于优化器生成更优的执行计划。
发一下 执行计划 尽量保存在文本里 看一下 再发一下 表结构信息 show create table BS_GL_POST
explain extended update BS_GL_POST set STAT_CD=‘P’ , TRANS_TM = ‘2024-11-10 18:20:36.000892’
WHERE 1 = 1 AND BLORG_NO = ‘0611’ AND INDEX_NO BETWEEN ‘102030111’ and ‘102032110’
AND ( PTXSP_MID_ENTRY_FLAG != ‘Y’ OR PTXSP_MID_ENTRY_FLAG IS NULL ) AND STAT_CD=‘O’
AND POST_DT < ‘2024-06-18’ AND VIRTUAL_FLAG=‘N’;
看着执行计划没有问题 查询一下我楼上发的 查询一下那几个视图信息
1、根据语句查询sql_id或者trace_id
select query_sql,svr_ip,TRACE_ID,sql_id,PLAN_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 ‘%update bs_gl_post set%’ order by elapsed_time desc
limit 10;
下面的信息 查一下看看
select * from V$OB_PLAN_CACHE_PLAN_STAT where sql_id=’’\G;
seelct * from V$OB_PLAN_CACHE_PLAN_EXPLAIN where PLAN_ID =’’\G;
select * from GV$SQL_PLAN_MONITOR where trace_id=’’\G;