count数据库优化oracle,迷惑性SQL性能问题排查与优化
:數據科學、人工智能從業者的在線大學。數據科學(Python/R/Julia)數據分析、機器學習、深度學習
作者簡介
戴秋龍,擁有超過八年的電信、保險、稅務行業核心系統ORACLE數據庫優化,優化經驗,具備豐富的行業服務背景。對Oracle數據庫有深刻的理解,擅長數據庫故障診斷,數據庫性能調優。
背景:
客戶某SQL,邏輯讀比較高。需要優化。也給出了AWR報告,AWR報告中主要幾個SQL都是類似的問題。
SQL_ID: g4nbv7twn23fw, 成本:3000 邏輯讀/次 40萬次/h
SELECT * FROM (SELECT XX.*, ROWNUM AS RN FROM (select count(*) from PARTY_CERT P inner join CUSTOMER C on P.PARTY_ID = C.PARTY_ID and C.STATUS_CD = '1100' where P.PARTY_ID in (:1 ) and P.STATUS_CD in (:2 ) and P.IS_DEFAULT = '1') XX WHERE ROWNUM <= 1000 ) XXX WHERE RN > 0
分析:
查詢出綁定變量的值帶入SQL,發現只有9個邏輯讀。與AWR報告不符合
可能有讀者認為性能問題在ID=5笛卡爾積問題,但從事后看問題不在這里。此時陷入僵局。但ASH視圖中或許能給出線索。
通過ash分析,更多的性能消耗在執行計劃的第9步。也就在C表(CUSTOMER)的回表上。
SQL中得出C表用到兩個字段 C.PARTY_ID,C.STATUS_CD。PARTY_ID上建有索引,回表就是為了訪問STATUS_CD字段。
因此建議建立索引index C ( PARTY_ID, STATUS_CD ); 這樣可以避免回表。
針對該SQL的優化建議是建立索引。
實施組建立索引后,從后期多份AWR報告中,該SQL平均330邏輯讀/次。
思考能否繼續優化
未優化之前帶入綁定變量9邏輯讀但AWR報告中平均3000邏輯讀。結合起來看是否是數據分布不均衡導致呢?
排查中發現C表 PARTY_ID字段的選擇性 98%,結合綁定變量繼續排查。
如圖:就是一個值在表中有10萬,其他值在表中只有1條。
當PARTY_ID = 15151723602037,回表需要回10萬次。把該值帶入SQL中。邏輯讀7770/次。是它把平均邏輯讀拉到3000.針對該問題上文已經有相關建議。那能否進一步優化?
探討:以下探討在沒有建立新索引的基礎上
既然數據分布不均衡,是否可以通過收集直方圖來改善性能?答案是否定的。
做好測試環境。
( 建立測試表:CUSTOMER_test。導入全部數據,建立相關索引,收集直方圖 ) 執行SQL,SQL效率更差,15萬邏輯讀/次
回到SQL中。分析SQL,SQL只是需要count(1),統計類型的,可以考慮用半連接
需要和業務確認是否可以改成半連接。( 此處不討論業務,只討論這種數據分布情況下如何優化 )因為針對數據分布不均衡半連接效果比較好。
改寫SQL:( 帶入數據最多的值 )
SELECT * FROM (SELECT XX.*, ROWNUM AS RN FROM (select count(1)
from CUST_YC_APP.PARTY_CERT P where P.PARTY_ID in (15151723602037)
And P.PARTY_ID in( select C.PARTY_ID from CUSTOMER_test C
where C.STATUS_CD = '1100' ) and P.STATUS_CD in ('1000')
and P.IS_DEFAULT = '1') XX WHERE ROWNUM <= 1000) XXX WHERE RN > 0;
改成in后不添加hints就會走全表,1286邏輯讀/S
添加hint/*+ nl_sj index(c) */9邏輯讀/次
SQL無法自動走最佳的執行計劃,需要綁定hints才走。
如何自動用最佳執行計劃呢?
刪除直方圖。
刪除直方圖后P.PARTY_ID in (15151723602037)的數據量雖然很多但CBO評估該數據量1條,直接走了hash join ( 有時候也會結合 C.PARTY_ID = P.PARTY_ID評估出 C.PARTY_ID =15151723602037 也是1條,直接走笛卡爾積關聯,類似開頭的問題)。而不是最好的執行計劃。
收集直方圖,會走索引,刪除直方圖會走hash/笛卡爾積關聯.就是得不到半連接
似乎陷入了困境。
設置數據選擇性。
幫助CBO評估 P表返回的數據,其對精確度要求也不高,甚至只要多評估幾條,讓CBO傾向選擇走半連接即可。
DBMS_STATS.set_column_stats(colname =>'PARTY_ID',distcnt => 1645919);
1645919 大約數據總量的30%,
測試SQL,看SQL是不是直接選擇最好的執行計劃。
執行計劃果然是nested_loop seml 關聯并且走索引。就是目前探討的最好的執行計劃。9邏輯讀/次
總結:
分析并且優化該SQL,有注意的地方有6點
笛卡爾積關聯,并不是性能瓶頸。
數據特殊分布,數據集中在某個值,這個值帶來嚴重的索引再回表。
結合數據分布把SQL改成半連接形式,成本明顯減少。
由于特殊分布,收集直方圖當測試特殊分布的值時候會帶來大表全表掃描,不收集直方圖會帶來hash join 不是我們想要得到的 nested_loop seml。
設置統計信息既能固定走索引掃描,(無論此表中數據情況都是索引掃描效率最高),又能滿足最好的關聯方式nested_loop seml。
最終的實施優化方案采用最簡單直接的方案,而不是我們文中探究的改SQL,設置統計信息等。而且最終效果還不錯。
總結
以上是生活随笔為你收集整理的count数据库优化oracle,迷惑性SQL性能问题排查与优化的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常规计算机 符号键是,电脑键盘上的字母和
- 下一篇: oracle 31693,ORACLE