Oracle的Index-3(轉)

Rounders發表於2007-08-06
Oracle的Index-3[@more@]

三講,索引再好,不用也是白搭

拋開前面所說的,假設你設定了一個非常好的索引,任何傻瓜都知道應該使用它,但是Oracle 卻偏偏不用,那麼,需要做的第一件事情,是審視你的 sql 語句。
Oracle 要使用一個索引,有一些最基本的條件:
1, where 子句中的這個欄位,必須是複合索引的第一個欄位;
2, where 子句中的這個欄位,不應該參與任何形式的計算
具體來講,假設一個索引是按 f1, f2, f3的次序建立的,現在有一個 sql 語句, where 子句是 f2 = : var2, 則因為 f2 不是索引的第1個欄位,無法使用該索引。
第2個問題, 則在我們之中非常嚴重。以下是從 實際系統上面抓到的幾個例子:
Select jobid from mytabs where isReq='0' and to_date (updatedate) >= to_Date ( '2001-7-18', 'YYYY-MM-DD');

………
以上的例子能很容易地進行改進。請注意這樣的語句每天都在我們的系統中執行,消耗我們有限的cpu 和 記憶體資源。
除了1,2這兩個我們必須牢記於心的原則外,還應儘量熟悉各種運算子對 Oracle 是否使用索引的影響。這裡我只講哪些操作或者運算子會顯式(explicitly)地阻止 Oracle 使用索引。以下是一些基本規則:
1, 如果 f1 和 f2 是同一個表的兩個欄位,則 f1>f2, f1>=f2, f1
2, f1 is null, f1 is not null, f1 not in, f1 !=, f1 like ‘%pattern%’;
3, Not exist
4, 某些情況下,f1 in 也會不用索引;
對於這些操作,別無辦法,只有儘量避免。比如,如果發現你的 sql 中的 in 操作沒有使用索引,也許可以將 in 操作改成 比較操作 + union all。筆者在實踐中發現很多時候這很有效。
但是,Oracle 是否真正使用索引,使用索引是否真正有效,還是必須進行實地的測驗。合理的做法是,對所寫的複雜的 sql, 在將它寫入應用程式之前,先在產品資料庫上做一次explain . explain 會獲得Oracle 對該 sql 的解析(plan),可以明確地看到 Oracle 是如何最佳化該 sql 的。
如果經常做 explain, 就會發現,喜愛寫複雜的 sql 並不是個好習慣,因為過分複雜的sql 其解析計劃往往不盡如人意。事實上,將複雜的 sql 拆開,有時候會極大地提高效率,因為能獲得很好的最佳化。當然這已經是題外話了。

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

相關文章