天天看點

一則簡單示例看Oracle的“無私”健壯性

Oracle的強大之處就在于他能總幫助讓你選擇正确的執行計劃,即使你給了它錯誤的訓示。

實驗:

1. 建立測試表:

一則簡單示例看Oracle的“無私”健壯性

收集統計資訊:

一則簡單示例看Oracle的“無私”健壯性

建立B樹索引:

一則簡單示例看Oracle的“無私”健壯性

2. 執行select id from tbl_plan;檢視它的執行計劃:

一則簡單示例看Oracle的“無私”健壯性

因為建立了B樹索引,正常講可以從索引中獲得id的值,不用全表掃描,但這裡使用了全表掃描的方式。

即使使用了HINT,這依舊使用的是全表掃描:

一則簡單示例看Oracle的“無私”健壯性

原因在于這是個B樹索引,不會存儲NULL值,盡管這張表沒有NULL值。如果直接從可能包含NULL值的B樹索引中查詢記錄,NULL值不會存儲于索引,就會漏一些記錄,那麼查詢結果就會有錯,是以Oracle在此并沒有選擇使用索引掃描,而是進行的全表掃描。

3. 将id字段設為非空:

一則簡單示例看Oracle的“無私”健壯性

相當于這是一個唯一性索引了。

再執行select id from tbl_plan;:

一則簡單示例看Oracle的“無私”健壯性

Oracle選擇的是索引快速全掃描,因為id是索引字段,直接從索引中獲得值是最快速的方式。

如果是使用了HINT的方式:

一則簡單示例看Oracle的“無私”健壯性

這使用的是索引全掃描,不如索引快速全掃描,但至少HINT起到了作用,原因就在于從非空索引中獲得值是一種可靠的方式,是以Oracle允許HINT的使用。

總結:

從上面的簡單示例可以看到,Oracle總會幫你選擇正确的執行計劃,即使你将錯誤的資訊給了Oracle,Oracle這種“無私”的精神值得我們學習,如果我們的應用系統也是這樣足夠健壯,那就更好了。