一、优化背景
两次收到短信警告,数据库CPU使用率过高(超过90%),初步判读是SQL需要优化
二、准备工作
2.1、生成AWR报告
以oracle用户登录到数据库服务器→
进入SQLPLUS→执行脚本(@?/rdbms/admin/awrrpt.sql)
→设定生成报告的格式(HTML或者text)→设置报告时间段的天数(根据警告)→
设置报告开始和结束的时间点(覆盖警告时间)→获取报告
具体步骤可参考:https://blog.csdn.net/bbliutao/article/details/51375693
2.2、查看报告
AWR的内容很丰富,但已经知道是CPU使用率过高的问题,就直接定位到使用率的段落。


发现前四个占用时间长,使用CPU高。点击SQL id进入SQL语句,获取SQL 内容。
#查看表属于哪个用户
SELECT * FROM DBA_TABLES WHERE TABLE_NAME='XXX';
#查看表的数据量
select count(*) from LC0019999.XXX;
#查看表中是否有索引
select * from user_indexes where table_name = 'XXX';
#索引在哪个字段
select COLUMN_NAME,INDEX_NAME from all_IND_COLUMNS where table_name = 'ROBXDJ' and COLUMN_NAME='ROBXDJ_NM'order by index_name;
2.3 查看执行计划
在SQL text前加上 explain plan for ,运行之后查看执行计划。
SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY('PLAN_TABLE'));

发现问题:全表扫描和嵌套循环占用时间长,使用CPU高。
三、解决问题:
问题1、全表扫描
想法:表数据量大同时where条件后表字段未加索引
解决方法:获取该表已经存在的索引列
SELECT A.UNIQUENESS , B.INDEX_NAME , B.COLUMN_NAME
FROM all_INDEXES A, all_IND_COLUMNS B
WHERE A.TABLE_NAME = B.TABLE_NAME
AND A.INDEX_NAME = B.INDEX_NAME
AND A.TABLE_NAME = 'TT_TEMP_S_SEND_DATA';
果然发现where条件后表字段未加索引(S.M_ID),只有ID列存在唯一索引(应该是主键)
同时该表中记录用1700W条。
加上索引:
CREATE INDEX INDEXTEST_20230203
ON ZQSY.TT_TEMP_S_SEND_DATA (M_ID);
退出SQL plus,再次进入查看执行计划。发现已经走索引了,同时CPU使用率也下降了,时间也下去了,问题解决。
参考链接:https://cloud.tencent.com/developer/article/1648496




