【背景】
2019年11月7日週四發版結束前,應用反饋說有一條sql語句執行時間變長,原來整個功能需要8秒左右,現在大概需要20秒鐘,他們鎖定一個模塊的sql語句,發現這條sql執行時間在10秒左右,現在需要分析SQL問題所在。
【正文】
溝通發現存在一個現象,查詢10月到11月的數據正常,查詢11月到12月就會變慢,從10月到12月也不存在問題,10月到11月數據量是2805條,11月,二線提醒有可能存在因統計信息導致的謂詞越界。
以下是執行計劃:
實際執行時間爲24.29秒,其中在第4步的嵌套循環耗費24.18秒,第23步耗費23.71秒;查詢統計信息發現最近一次收集在10月29日,統計行數爲585690條,實際count發現是605649條,統計信息基本準確。
查看E-Rows和對應的A-Rows發現第12步表TABLE_SCHEDULE預估返回8行,實際返回18376行,說明在條件範圍內的統計信息存在較大偏差,錯誤的統計信息導致數據庫採用NESTED LOOPS方式的執行計劃,第10步的NESTED LOOPS實際要循環18376次;最終由於各層的HASH JOIN結果導致最終需要進行26496次嵌套循環,嚴重影響查詢性能。
現在需要更新表TABLE_SCHEDULE的統計信息
exec dbms_stats.gather_table_stats(ownname => 'USERNAME',tabname => 'TABLE_SCHEDULE',granularity => 'ALL',cascade => true);
收集完成後,再次查看執行計劃,已恢復正常:
附:
執行計劃獲取步驟
Set linesize 500
set termout off
1、alter session set statistics_level = all;
2、執行SQL語句
3、查看執行計劃
select * from table(dbms_xplan.display_cursor(null,null,'ADVANCED ALLSTATS LAST PEEKED_BINDS'));