關於查詢轉換的一些總結

kl911發表於2008-04-28

對於查詢轉化,是最佳化器的一種功能,較簡單的回答,最佳化器會根據它的推測將你的sql語句以另一種方式展現出來,當然查詢結果肯定不變,但效能通常都是較優的。

1. NO_UNNEST: 知道最佳化器關閉查詢unnesting,也就是不讓它將子查詢保持在VIEW中,打散任何子查詢。而unnest則是要求使用子查詢轉換。

這裡還必須提到一個隱藏引數 "_tablescan_cost_plus_one", 這個引數在8i裡預設值是false的,到了9i,10g才變成true.這將導致9i以上的full scan的成本增加1,另外還有initrans這個表現出的變化,9i中其預設值為2,即使你指定為1,或者資料字典申明為1。

但如果用create table .. as select 方式建立表,則在ITL(Interested Transaction List)中,事物槽會變成3,即這是block的實際數量為3,而不是2。這樣就使得full scan的成本在理想情況下,增加了2.


2. 對於8i,執行計劃裡可知,最佳化器忽略了子查詢的實際成本,只有外部查詢的一次全掃描,這使最佳化器毫不猶豫地選擇full scan。而9i呢,則是將子查詢的數量乘上外部表的成本,再加上外部表的一次全掃名的成本,這樣就能夠反映實際情況嗎?在不知道子查詢結果集的時候,就悲觀地認為子查詢全表掃描的結果就是外部查詢的結果多少有點武斷。於是10g在此基礎上作了一定的改變,對成本的計算,按照實際資料的分佈,得到一個相對合理的百分比;而對cardinality則用5%(對於繫結變數的估計值)計算出一個相對合理,至少在一般分佈的條件下合理的值,計算方式如下selectivity*num of rows*5% . 這都得益於一個隱藏引數: _optimizer_correct_sq_selectivity,10g預設為true,如果改為false,這個值則為5%*5%*num of rows(5%一個是父表一個是子表);

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/661919/viewspace-1003134/,如需轉載,請註明出處,否則將追究法律責任。

相關文章