萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> oracle教程 >> Oracle中建立索引並強制優化器使用

Oracle中建立索引並強制優化器使用

當WHERE子句對某一列使用函數時,除非利用這個簡單的技術強制索引,否則Oracle優化器不能在查詢中使用索引。 通常情況下,如果在WHERE子句中不使用諸如UPPER、REPLACE 或SUBSTRD等函數,就不能對指定列建立特定的條件。但如果使用了這些函數,則會出現一個問題:這些函數會阻礙Oracle優化器對列使用索引,因而與采用索引的情況相比較,查詢會花費更多的時間。

慶幸的是,如果在使用函數的這些列中包含了字符型數據,可以用這樣一種方法修改查詢語句,以達到強制性使用索引,更有效地運行查詢。這篇文章介紹了涉及的技術,並說明了在兩種典型情況下怎樣實現。

大小寫混合情況

在討論由於函數修改了列的內容,如何強制使用索引前,讓我們首先看看為什麼Oracle優化器在這種情況下不能使用索引。假定我們要搜尋包含了大小寫混合的數據,如ADDRESS表的NAME列。因為數據是用戶輸入的,我們無法使用已經統一改為大寫的數據。為了找到每一個名為john的地址,我們使用包含了UPPER子句的查詢語句。如下所示:

SQL> select address from address where upper(name) like 'JOHN';

在運行這個查詢語句前,如果我們運行了命令"set autotrace on", 將會得到下列結果,其中包含了執行過程:

ADDRESS
cleveland
1 row selected.
Execution Plan
SELECT STATEMENT
TABLE ACCESS FULL ADDRESS

可以看到,在這種情況下,Oracle優化器對ADDRESS 表作了一次完整的掃描,而沒有使用NAME 列的索引。這是因為索引是根據列中數據的實際值建立的,而UPPER 函數已經將字符轉換成大寫,即修改了這些值,因此該查詢不能使用這列的索引。優化器不能與索引項比較"JOHN",沒有索引項對應於"JOHN"-只有"john" 。

值得慶幸的是,如果在這種情況下想要強制使用索引,有一種簡便的方法:只要在WHERE 子句中增加一個或多個特定的條件,用於測試索引值,並減少需要掃描的行,但這並沒有修改原來SQL 編碼中的條件。以下列查詢語句為例:

SQL> select address from address where upper(name) like 'JO%' AND (name
like 'J%' or name like 'j%');

使用這種查詢語句(已設置AUTOTRACE),可得到下列結果:

ADDRESS
cleveland
1 row selected.
Execution Plan
SELECT STATEMENT
CONCATENATION
TABLE ACCESS BY INDEX ROWID ADDRESS
INDEX RANGE SCAN ADDRESS_I
TABLE ACCESS BY INDEX ROWID ADDRESS
INDEX RANGE SCAN ADDRESS_I

現在,優化器為WHERE 子句中AND 聯結的兩個語句中每一個語句確定的范圍進行掃描----第二個語句沒有引用函數,因而使用了索引。在兩個范圍掃描後,將運行結果合並。

在這個例子中,如果數據庫有成百上千行,可以用下列方法擴充WHERE 子句,進一步縮小掃描范圍:

select address from address where
upper(name) like 'JOHN' AND (name like 'JO%'
or name like 'jo%' or name like 'Jo' or name like 'jO' );

  • 共2頁:
  • 上一頁
  • 1
  • 2
  • 下一頁
copyright © 萬盛學電腦網 all rights reserved