【YashanDB知識庫】由於hist_head$中analyze time小於tab$中analyze time導致的sql語句執行慢

YashanDB發表於2024-09-27

本文內容來自YashanDB官網,具體內容請見https://www.yashandb.com/newsinfo/7459465.html?templateId=1718516

問題現象

某局點yashandb cpu使用率100%,經線上分析是由於幾個sql執行慢,其中一個sql為簡單的單行等值繫結變數過濾+排序。

經分析執行計劃,相對以前有所變化,走了另外一個索引(效率低)。

問題的風險及影響

sql語句執行慢,客戶的業務受到影響。作業系統cpu 100%可能導致當機。

問題影響的版本

22.2.10.100

問題發生原因

hist_head$中表對應列的analyze time小於tab$中表的analyze time,在執行到estColEqualOrNotParam方法時,由於第一個引數colStats為null導致獲得預設selectivity(0.04)後退出。而實際選擇率為0.00003,相差甚遠,最佳化器最終估算出來的cost不準,選擇了錯誤的執行計劃。

解決方法及規避方式

客戶現網透過將錯誤的索引invisiable後規避。

問題分析和處理過程

現網錯誤的執行計劃及估算出來的rows及cost(sql語句中有hint,可以忽略,實際不加hint也走的是這個執行計劃):

過濾條件中sub_account_id的選擇性很好,表的總資料量為6千萬左右,count(distinct)值為200萬左右。很明顯,上圖中執行計劃估算出來的rows是明顯失真的。

實際正確的執行計劃及cost如下(where語句中多了幾個predicate,不影響總量本質):

實際最佳化器在載入列的統計資訊用於估算時,如果hist_head$中analyze time小於tab$中analyze time,或者hist_head$中沒有表中相關列的資料,那麼就會用預設的selectivity(0.04)來做過濾條件估算,最終導致執行計劃走偏。

經驗總結

hist_head$中存放了列的普通統計資訊,histgrm$中存放了列的直方圖資訊

相關文章