oracle基於成本的優化器(cost based optimizer, cbo) 最令人沮喪的一點就是它看上去可能會不定期的改變sql語句的執行計畫的趨勢.通常很難來確定執行計畫為什麼改變.
理解計畫的不穩定性
cbo的主要輸入有3個.
因此, 除非上面這3點中的某乙個改變了, 否則執行計畫是不應該變化的. 我相信計畫不穩定性導致的挫敗感主要是由於我們認為」任何事情都沒有變化」. 而實際上某些事情的確發生了變化.
1) 統計資訊的變化
在大多數系統中都頻繁收集物件級統計資訊. 預設情況下, 10g 和 11g 都有乙個在晚上執行的後台作業來計算新的統計資訊. 如果這些後台作業也在你的系統中執行, 那也就意味著每天你都可能會有得到乙個新的執行計畫的機會.
2) 環境的改變
有很多引數可能會影響優化器的計算. 當前對乙個語句進行解析時起作用的設定可以通過啟用 10053 追蹤來獲得.
3) sql 語句的改變
這裡指的是你寫的sql語句沒變, 但是, 優化器將它轉換的時候發生了變化. 例如:
如果乙個語句引用了檢視並且底層的檢視發生了變化, 語句也就改變了
如果乙個語句使用繫結變數而從變數所傳過來的值發生了變化, 語句也就改變了. 但是, 我們經過多年的培訓被教育說, 使用繫結變數會避免硬解析, 但是 oracle 9i 引入了乙個特性, 准許優化器在確定執行計畫的解析過程中」窺視」繫結變數的值. 這就是你可能已經聽說的聲名不佳的繫結變數窺視. 它也是引起計畫穩定性問題的主要原因之一.
繫結變數窺視
當 oracle 8i 中引入直方圖資訊的時候, 他們就提供了一種機制使得優化器可以識別出某一列的值的不是均勻分布的, 經典的例子就是100條記錄只有兩個非重複值, 其中值」y」出現了99次而值 「n」只出現1次. 如果沒有直方圖資訊, 優化器就會一直假設不管你需要的是y, 還是n的資料, 都將會得到一半的記錄 100/2=50, 因此, 你總是需要進行全表掃瞄而不是使用該列上的索引. 而直方圖資訊, 假設它是準確的, 能夠讓優化器知道資料分布是不均勻的. 其中幾乎整張表的值都是 y, 只有1%為n. 這就使得不管在where子句中指定了哪個值, 優化器都可以得出恰當的執行計畫. 那麼讓我們來考慮一下這樣所帶來的影響, 這樣可以改善對 y 值進行查詢的響應時間嗎? 答案是否定的,(仍然需要全表掃瞄, 99%的資料當然需要全表掃瞄) 另外, 為了讓優化器能夠使用直方圖資訊, 你不得不在sql語句中使用常量, 因此你必須向下面這樣來書寫sql語句:
select xyz from table1 where column1 = 『y』;
select xyz from table1 where column1 = 『n』;
現在進入主題: 繫結變數窺視, 它准許優化器窺視繫結變數值, 然後使用直方圖資訊來得出如同使用常量時那樣恰當的執行計畫. 新特性的問題在於它只看一次變數, 就是在對語句進行解析的時候, 現在讓我們假設一種更切合實際的情況, 你有一張10 000 000行資料的表, 其中99%的值為y, 只有1%的值為n, 在這個例子中,如果第一次執行語句時傳遞的值是y, 那麼就將會鎖定全表掃瞄執行計畫, 直到語句被迫進行重新解析, 即使在語句下一次執行過程中傳遞的值是n 也一樣. 讓我們來考慮一下這樣所帶來的影響, 在你得到全表掃瞄執行計畫(因為你第一次傳遞的值是 y )之後, 不管再傳遞什麼值, 語句的行為都將是一樣的. oracle將一直進行全表掃瞄, 總是做一樣多的工作, 通常執行時間也基本相同, 從使用者的觀點來看, 這看上去似乎是合理的, 效能是一致的(順便說一句, 沒有直方圖資訊時的情況就是這樣的), 另一方面, 如果在第一次執行的時候傳遞的值是n, 而選用了索引執行計畫, 在值為n的時候執行將會比以前快, 但對於值為 y 的執行卻會令人難以置信的慢. 這絕對不是使用者想要的.
解決以上問題, 在11g 中通過所謂自適應游標共享所實現.
綜上, 繫結變數也不是所有情況都可以使用的.
注: 自適應游標共享 介紹 引數(cursor_sharing 如果設定為 force, 那麼oracle 將會把所有的常量轉換為繫結變數)
適當使用常量
給優化器一些提示(hint) , 優化器可以按照自己的意願接受或忽略. 當生命了無效的提示時不會返回任何錯誤或警告資訊.
v$sql_hint 提供乙個有效提示的列表
提示可以通過以乙個加號(+)開頭嵌入到注釋中來應用到單獨的sql 語句中. 任何緊跟在 select, update, insert 或 delete 關鍵字之後以 (+)開頭的注釋都會被優化器評估. 注釋中可以包含多個提示.
繫結變數窺視可能是最廣泛也是最難對付的原因, 儘管大多數使用者並不十分情願關閉繫結變數窺視」特性」(_optim_peek_user_binds), 這一點是可以理解的, 但將它完全關閉實際上是可行的選擇. 有很多生產系統都採用了這種方法. 除了將繫結變數完全關閉以外, 在需要直方圖資訊處理偏態資料分布的列上恰當使用常量, 實際上是在處理計畫穩定性問題的同時, 還能使得優化器具有選擇絕對最優執行計畫能力的唯一有效途徑.
oracle 資料庫11g提供了一種新的處理計畫不穩定的方法. sql執行計畫基線. 通過使用基線, 不准許一條語句切換到乙個比已經執行過的顯著慢的多的執行計畫上. 這個心的機制以來於看上去與sql概要檔案非常相似的基線. 事實上, 它們也是以同樣的結構儲存在資料字典中. 基線的特徵如下:
mysql穩定性 MySQL的穩定性
isam表處理器 穩定 它管理所有在mysql 3.22和早期版本中的資料的儲存和檢索。在所有mysql版本中,中已經沒有乙個單獨 報告的 錯誤。得到乙個損壞的資料庫表的唯一已知方法是在乙個更新中途殺死伺服器,即使這樣也不大可能破壞任何資料而不能挽救,因為所有資料在每個查詢之間被倒入 flush 到...
排序穩定性
這幾天筆試了好幾次了,連續碰到乙個關於常見排序演算法穩定性判別的問題,往往還是多選,對於我以及和我一樣拿不準的同學可不是乙個能輕易下結論的題目,當然如果你筆試之前已經記住了資料結構書上哪些是穩定的,哪些不是穩定的,做起來應該可以輕鬆搞定。本文是針對老是記不住這個或者想真正明白到底為什麼是穩定或者不穩...
穩定性檢驗
3種主要的穩健性檢驗途徑 1.從資料出發,替換不同的樣本進行檢驗樣本是否有問題 2.從變數出發,根據其它不同指針對樣本進行分類後,檢查分類後的樣本是否對y特徵的顯著性有影響 3.從計量方法出發,用不同的工具或檢驗方法。可以用ols,fix effect,gmm等來回歸,看結果是否依然robust 方...