2009-07-28 38 views
22

Oracle中的substr或LIKE更快嗎?

WHERE substr(my_field,1,6) = 'search' 

WHERE my_field LIKE 'search%' 

在甲骨文更快,或者會不會有沒有區別?

+0

也http://stackoverflow.com/questions/8646623/what-is-the-difference-between-instr-and-like-in-oracle – Vadzim 2016-12-13 11:41:00

回答

19

假設最高性能是目標,我會理想地選擇SUBSTR(my_field,1,6)並創建一個基於函數的索引來支持查詢。

CREATE INDEX my_substr_idx 
    ON my_table(substr(my_field,1,6)); 

正如其他人所指出的,SUBSTR(my_field,1,6)將無法​​對MY_FIELD使用常規指標。 LIKE版本可能會使用索引,但是在這種情況下,優化器的基數估計通常很差,因此很有可能在有用時不使用索引,或者在表掃描更可取時使用索引。爲實際表達式編制索引將爲優化器提供更多信息來處理,因此更有可能正確選擇索引。比我更聰明的人可能會建議一種方法來使用11g中的虛擬列的統計信息來爲優化器提供LIKE查詢的更好信息。

如果6是一個變量(即您有時想搜索前6個字符,有時想搜索不同的數字),那麼您可能不會提供基於函數的索引來支持該查詢。在那種情況下,你可能會更喜歡用LIKE公式做出的優化器決策的變幻莫測。

9

提供的兩個選項中,絕對是LIKE。子字符串方法必須針對表中的所有行執行。使用LIKE將允許使用索引。

要檢查我的答案,只需分析結果。這應該是明確的一天。

+0

看到像可能是更快的,不是絕對。即使有索引,根據選擇性可能會也可能不會被使用。 – 2009-07-28 22:11:08

+0

@Alex - 確實如此。但是在所有情況下,最好盡力爭取最佳,並允許服務器使用索引(如果可用)。使用子字符串方法保證不會使用索引。 – beach 2009-07-28 22:13:35

2

如果您在my_field上有索引,那麼LIKE可能會更快。做你自己的基準。

0

我會分析這兩個。但我猜想'LIKE'會更快,因爲它使用索引上的二進制搜索(如果該字段已編入索引)。如果使用SUBSTR方法,則最終將進行全表掃描,因爲Oracle必須逐行處理該函數。

1

有真的在這裏的兩個問題:

  1. 對於哪一個甲骨文產生了更準確的基數和成本估計?
  2. 哪種方法在潛在訪問方法上更靈活?

這可能因版本而異,但兩者都很容易測試,並且這種方式可以確保您獲得最適合您的版本和數據的信息。

運行的執行計劃使用兩個查詢...

explain plan for 
select ... from ... where my_field LIKE 'search%'; 

select * from table(dbms_xplan.display); 

explain plan for 
select ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

您可能會看到在執行計劃的差異,這取決於索引的存在等。,而且將基數估計值與您得到的實際結果進行比較:

select count(*) from ... where my_field LIKE 'search%'; 

其中一種方法可能比另一種方法準確得多。

如果他們都不是很準確此查詢預計的時間,然後考慮使用動態採樣,以改進估計一個不平凡的量運行,因爲錯誤的基數估計值優化程序可能選擇次優無論如何,訪問方法。

explain plan for 
select /*+ dynamic_sampling(4) */ ... from ... where substr(my_field,1,6) = 'search'; 

select * from table(dbms_xplan.display); 

就索引使用情況而言,兩種方法都可以使用基於索引的訪問方法。 LIKE謂詞可能更適合索引,可以使用範圍掃描或快速全索引掃描。 SUBSTR方法當然可以使用快速全索引掃描,但優化程序是否會考慮範圍掃描最好在您自己的版本上進行測試 - 我的回憶是,它不會但是誰說這個substr(my_column, ,n)不會被認爲是一個特例,如果不是現在,那麼將來呢?

2

如果你有沒有索引比沒有差異。因爲oracle正在執行全表掃描並評估每行的表達式。 您可以在列上放置索引以加快查詢速度。

CREATE INDEX my_like_idx 
ON my_table(my_field); 

該索引更靈活,並加速查詢使用類似。它將適用於以字符開頭並在末尾佔位符(%)的任何比較。 Oracle正在進行索引範圍掃描以查找所有匹配的行。

CREATE INDEX my_substr_idx 
ON my_table(substr(my_field,1,6)); 

此索引加速與substr的查詢。但索引是非常特殊的比較只有前6個字符。

如果查詢中間的一段起始段。創建一個基於函數的索引將有所幫助

WHERE substr(my_field,2,5) = 'earch' 
WHERE my_field like '%earch%'