45. 需要當心的where子句
某些select 語句中的where子句不使用索引。 這裡有一些例子。
在下面的例子裡, 『!=』 將不使用索引。 記住, 索引只能告訴你什麼存在於表中, 而不能告訴你什麼不存在於表中。
不使用索引:
select account_name
from transaction
where amount !=0;
使用索引:
select account_name
from transaction
where amount >0;
下面的例子中, 『||』是字元連線函式。 就象其他函式那樣, 停用了索引。
不使用索引:
select account_name,amount
from transaction
where account_name||account_type=『amexa』;
使用索引:
select account_name,amount
from transaction
where account_name = 『amex』and account_type=『 a』;
下面的例子中, 『+』是數學函式。 就象其他數學函式那樣, 停用了索引。
不使用索引:
select account_name, amount
from transaction
where amount + 3000 >5000;
使用索引:
select account_name, amount
from transaction
where amount > 2000 ;
下面的例子中,相同的索引列不能互相比較,這將會啟用全表掃瞄。
不使用索引:
select account_name, amount
from transaction
where account_name = nvl(:acc_name,account_name);
使用索引:
select account_name, amount
from transaction
where account_name like nvl(:acc_name,『%』);
譯者按:如果一定要對使用函式的列啟用索引, oracle新的功能: 基於函式的索引(function-based index) 也許是乙個較好的方案。
create index emp_i on emp (upper(ename)); /*建立基於函式的索引*/
select * from emp where upper(ename) = 『blacksnail』; /*將使用索引*/
46. 連線多個掃瞄
如果你對乙個列和一組有限的值進行比較, 優化器可能執行多次掃瞄並對結果進行合併連線。
舉例:select *
from lodging
where manager in (『bill gates』,『ken muller』);
優化器可能將它轉換成以下形式
select *
from lodging
where manager = 『bill gates』or manager = 『ken muller』;
當選擇執行路徑時, 優化器可能對每個條件採用lodging$manager上的索引範圍掃瞄。 返回的rowid用來訪問lodging表的記錄 (通過table access by rowid 的方式)。 最後兩組記錄以連線
(concatenation)的形式被組合成乙個單一的集合。
explain plan :
select statement optimizer=choose
concatenation
table access (by index rowid) of lodging
index (range scan ) of lodging$manager (non-unique)
table access (by index rowid) of lodging
index (range scan ) of lodging$manager (non-unique)
譯者按:本節和第37節似乎有矛盾之處。
47. cbo下使用更具選擇性的索引
基於成本的優化器(cbo, cost-based optimizer)對索引的選擇性進行判斷來決定索引的使用是否能提高效率。
如果索引有很高的選擇性, 那就是說對於每個不重複的索引鍵值,只對應數量很少的記錄。 比如, 表中共有100條記錄而其中有80個不重複的索引鍵值。 這個索引的選擇性就是80/100 = 0.8 . 選擇性越高, 通過索引鍵值檢索出的記錄就越少。
如果索引的選擇性很低, 檢索資料就需要大量的索引範圍查詢操作和rowid 訪問表的操作。 也許會比全表掃瞄的效率更低。
譯者按: 下列經驗請參閱:
a. 如果檢索資料量超過30%的表中記錄數。使用索引將沒有顯著的效率提高。
b. 在特定情況下, 使用索引也許會比全表掃瞄慢, 但這是同乙個數量級上的區別。 而通常情況下,使用索引比全表掃瞄要快幾倍乃至幾千倍!
Oracle語句優化 個規則詳解
1.選用適合的oracle優化器 2.訪問table的方式oracle 採用兩種訪問表中記錄的方式 3.共享sql語句 4.選擇最有效率的表名順序 只在基於規則的優化器中有效 5.where子句中的連線順序。6.select子句中避免使用 7.減少訪問資料庫的次數 8.使用decode函式來減少處理...
Oracle語句優化 個規則詳解 10
42.使用提示 hints 對於表的訪問,可以使用兩種hints.full 和 rowid full hint 告訴oracle使用全表掃瞄的方式訪問指定表。例如 select full emp from emp where empno 7893 rowid hint 告訴oracle使用table...
oracle語句優化規則二
oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where條件之前,那些可以過濾掉最大數量記錄的條件必須寫在where子句的末尾。1.where子句中的連線順序。oracle採用自下而上的順序解析where子句,根據這個原理,表之間的連線必須寫在其他where...