本文內容來自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$中存放了列的直方圖資訊