檢視mysql硬解析 幾種常見重新硬解析的原因

2021-10-17 17:31:34 字數 2431 閱讀 2506

經常有客戶提說某個sql的執行計畫變差了,導致出現了效能問題,進而就問為啥解析出了新的

執行計畫。首先可以肯定突然出現了新的執行計畫表明sql進行了重新硬解析(注意重新硬解析不一定

產生新的執行計畫),那麼為啥好好的sql需要重新硬解析呢?今天我們就列舉幾種常見的原因:

1.自動收集統計資訊

為了保證sql的最佳執行效能,oracle需要找到乙個最優的執行計畫,基於cbo模式的優化器必須

要知道最新的統計資訊,例如條數,block數量,某個欄位的選擇率等,所以oracle每天凌晨都會執行一

個自動收集統計資訊的job,來收集那些變化超過10%的表的最新統計資訊,收集完成之後,理所當然

要對新來的sql進行使用,所以就需要進行硬解析。oracle 收集某個表統計資訊後預設是不會立即invalid

所有相關的cursor,因為這樣做太暴力,會引發硬解析相關的效能問題,所以巧妙的設計了一下,當某個相關sql執行的時候發現乙個依賴物件最近收集過統計資訊,便隨機的打個乙個時間戳,這個時間戳是

5個小時內某個時間戳,等到下次sql解析的時候若是發現了這個時間戳就會和當前時間進行比較,若是超過就說明已經到期,立即進行硬解析,否則還繼續進行軟解析。

2.沒有符合條件的child cursor 典型的如bind mismatch (其他原因可以參考v$sql_shared_cursor)

當某個sql使用了繫結變數的時候,oracle 會記錄cursor第一次硬解析時候的繫結變數的相關metadata,

當後續解析的時候便會進行檢查,若是發現繫結變數型別或長度不匹配就會進行重新解析,下面我們就用乙個小例子驗證一下:

create table maob_t as select from dba_tables ;

var b1 char(20);

exec :b1 := 'maob';

select count() from maob_t where table_name=:b1;

檢視cursor情況

select sql_id,child_number,first_load_time from v$sql where sql_text like '%count%maob_t%'

4v22rgk83gjnc 0 2017-12-15/22:52:46 <

把繫結變數型別變成varchar2,sql文字不變,再次執行:

var b1 varchar2(20);

exec :b1 := 'maob';

select count(*) from maob_t where table_name=:b1;

執行上述語句後再次檢視

select sql_id,child_number,first_load_time from v$sql where sql_text like '%count%maob_t%'

4v22rgk83gjnc 0 2017-12-15/22:52:46

4v22rgk83gjnc 1 2017-12-15/22:52:46

可以看到已經有兩個只cursor,進一步檢視cursor不能share的原因:

select sql_id,child_number,bind_mismatch from v$sql_shared_cursor where rownum<10 and sql_id='4v22rgk83gjnc'

sql_id,child_number bind_mismatch

4v22rgk83gjnc 0 n

4v22rgk83gjnc 1 y <<

可以看到由於繫結變數的原因造成的mismatch,所以硬解析產生了第二個子cursor。

3.oracle11g 提供了自適應游標功能(adaptive cursor sharing),如果表上的字段存在直方圖並且資料存在傾斜的場景下,那麼對於傳入不同的資料就會造成oracle重新嘗試硬解析。具體內容,可以參考另外一篇部落格。

4.cursor 已經被ageout 記憶體

我們都知道,oracle 對於記憶體管理機制和很多os管理記憶體機制一樣,都採用了lru(least recently used,最近最少使用)演算法,

cursor作為一種library cache 中的物件也不例外,若是某個sql解析需要share pool記憶體時,發現free list 上並沒有合適大小的記憶體塊(chunk)

就會觸發清理機制,那麼之前cursor 申請的chunk就依據lru演算法規則被清理掉,這種就是age out,需要注意的是,這個是oracle的

機制,並不是os上的swap機制,一旦某個cursor的被ageout出shared pool,那麼下次執行這個sql的時候就是重新硬解析。

5.除了上述幾種oracle自身的機制造成重新硬解析之外,也存在人為因素操作造成的可能

例如人為收集統計資訊,人為執行了flush shared_pool 操作,手工呼叫dbms_shared_pool.purge 來清理某個cursor

執行了ddl 語句等。

json解析的幾種方式 解析物流分揀常見的幾種方式

在物流配送中,由於倉庫的規模 訂單數量和貨物種類不同,分揀方式也不同。但是,常用的分揀方法大致可分為三類 人工分揀 半自動機械分揀裝置和分揀機自動分揀。今天我們就來分析一下現代物流分揀幾種方式的區別和特點是什麼?它是物流分揀最初的形態,以人工為主,僅需較小的裝置投入。但隨著電商的發展,訂單分揀量迅速...

mysql 常見的幾種日誌設定

mysql日誌是我們需要掌握的知識,下面就為您介紹幾個最常見的mysql日誌型別,如果您對mysql日誌方面感興趣的話,不妨一看。1 錯誤日誌 記錄啟動 執行或停止mysqld時出現的問題。my.ini配置資訊 enter a name for the error log file.otherwis...

mysql中常見的幾種索引

主鍵索引 資料列不允許重複,不允許為null,乙個表只能有乙個主鍵。唯一索引 資料列不允許重複,允許為null值,乙個表允許多個列建立唯一索引。可以通過 alter table table name add unique column 建立唯一索引 可以通過 alter table table na...