分析AWR报告发现业务问题
Jul072015
在分析SIT数据库的AWR报告时,发现有几条SQL每小时运行近50万次,由于新接触这个数据库,对业务不了解,还以为是在做压力测试,在解决了几条SQL后,开始关注这几条SQL,发现很严重的问题。以下是AWR报告中,相关的SQL信息:
其中SELECT语句如下:
SELECT COUNT(1) FROM CHGSHS.CMM_PROC_EXEC_L A WHERE A.PROC_NM = 'SP_MED_Q_END_BAT' AND A.STATUS_CD = 'S' AND A.LOG_NO <> :B1 AND ROWNUM <= 1
经查询,CMM_PROC_EXEC_L表大小6GB多,上面还有一个复合主键和两个符合索引。
CHGSHS@IVLDB > select segment_name,bytes/1024/1024/1024 bytes from user_segments where segment_name ='CMM_PROC_EXEC_L'; SEGMENT_NAME BYTES/1024/1024 ------------------------- --------------- CMM_PROC_EXEC_L 6584 CHGSHS@IVLDB > select index_name,column_name from user_ind_columns where table_name='CMM_PROC_EXEC_L'; INDEX_NAME COLUMN_NAME ------------------------------ ------------------------------ IX_CMM_PROC_EXEC_L_02 BGN_DTM IX_CMM_PROC_EXEC_L_02 PROC_NM CMM_PROC_EXEC_L_IX1 STATUS_CD CMM_PROC_EXEC_L_IX1 PROC_NM PK_CMM_PROC_EXEC_L LOG_NO
而且索引非常大,三个索引加一起,10GB左右。
CHGSHS@IVLDB > select segment_name,bytes/1024/1024/1024 bytes from user_segments where segment_name in ('CMM_PROC_EXEC_L','PK_CMM_PROC_EXEC_L','CMM_PROC_EXEC_L_IX1','IX_CMM_PROC_EXEC_L_02'); SEGMENT_NAME BYTES/1024/1024 ------------------------- --------------- CMM_PROC_EXEC_L 6584 IX_CMM_PROC_EXEC_L_02 4615 CMM_PROC_EXEC_L_IX1 4471 PK_CMM_PROC_EXEC_L 1664
再看看表结构。
CHGSHS@IVLDB > desc CMM_PROC_EXEC_L Name Null? Type ----------------------------------------------------- -------- ------------------------------------ LOG_NO NOT NULL NUMBER(22) TS_CD NOT NULL VARCHAR2(5 CHAR) PROC_NM VARCHAR2(100 CHAR) STATUS_CD VARCHAR2(1 CHAR) BGN_DTM DATE END_DTM DATE MSG VARCHAR2(1000 CHAR) RUN_SEC NUMBER(22,2) REM_SEC NUMBER(22,2) SQLCODE VARCHAR2(100 CHAR) SQLERRM VARCHAR2(1000 CHAR) WORK_ROWS NUMBER(22) CURR_ROWS NUMBER(22) INST_ID NOT NULL VARCHAR2(40 CHAR) INST_DTM DATE MDF_ID NOT NULL VARCHAR2(40 CHAR) MDF_DTM DATE
索引列都不是较大的字段,那么从以上信息就可以发现,索引存在较多的碎片。
CHGSHS@IVLDB > alter index CMM_PROC_EXEC_L_IX1 rebuild online; Index altered. CHGSHS@IVLDB > alter index IX_CMM_PROC_EXEC_L_02 rebuild online; Index altered. CHGSHS@IVLDB > select segment_name,bytes/1024/1024 from user_segments where segment_name in ('CMM_PROC_EXEC_L_IX1','IX_CMM_PROC_EXEC_L_02','CMM_PROC_EXEC_L'); SEGMENT_NAME BYTES/1024/1024 ------------------------- --------------- IX_CMM_PROC_EXEC_L_02 2054 CMM_PROC_EXEC_L_IX1 1730
这表肯定也存在较多的碎片,查询表的数据发现,这是张记录PL/SQL运行报错的日志表。
CHGSHS@IVLDB > select PROC_NM,BGN_DTM,MSG FROM CMM_PROC_EXEC_L where msg is not null and rownum <6; PROC_NM BGN_DTM MSG ---------------------------------------- ------------------- -------------------- PG_FUL_CMD.SP_FUL_CMD_SHOP_SHIP_BAT_C01 2015-07-03 14:45:02 没有出库指示对象 PG_FUL_CMD.SP_FUL_CMD_SHOP_SHIP_BAT_C02 2015-07-03 14:45:02 没有出库指示对象 PG_FUL_CMD.SP_FUL_CMD_SHOP_SHIP_BAT_C03 2015-07-03 14:45:02 没有出库指示对象 PG_FUL_CMD.SP_FUL_CMD_SHOP_SHIP_BAT_C04 2015-07-03 14:45:02 没有出库指示对象 PG_FUL_CMD.SP_FUL_CMD_SHOP_SHIP_BAT_C05 2015-07-03 14:45:02 没有出库指示对象
对于这样的日志表,每秒要操作几千次肯定是业务逻辑出了问题,向开发人员反馈,开人人员确认是业务逻辑出了问题,调整后在AWR报告中,这个SQL再未出现。
再看看索引信息:
INDEX_NAME COLUMN_NAME ------------------------------ ------------------------------ IX_CMM_PROC_EXEC_L_02 BGN_DTM IX_CMM_PROC_EXEC_L_02 PROC_NM CMM_PROC_EXEC_L_IX1 STATUS_CD CMM_PROC_EXEC_L_IX1 PROC_NM PK_CMM_PROC_EXEC_L LOG_NO
两个符合索引,全部存在PPROC_NM列,而且相对来讲这个列是较大的列,完全可以考虑把索引合并的呀。而且这个表是可以TRUNCATE的。