2008-09-25 100 views
11

Oracle中使用LIKE'string'vs ='string'會對性能產生什麼影響?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

比這

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

,但是這個慢是什麼?

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

我的測試表明第二和第三個例子完全一樣。如果那是真的,我的問題是,爲什麼使用「=」?

+0

你做了什麼測試? – 2008-09-25 16:55:41

+0

1 - 針對大表使用兩種方法多次執行語句,注意執行時間 2 - 查看解釋計劃 – JosephStyons 2008-09-26 14:03:12

回答

17

當您使用綁定變量時,您應該在Oracle中使用除數據倉儲或其他批量數據操作以外的任何其他變量,這兩者之間有明顯區別。

取的情況下:

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE :b1 

Oracle無法知道的值:b1爲「%SOME_VALUE%」,或「SOME_VALUE」等等,直到執行時間,所以它會使的估計基於啓發式的結果的基數,並提出一個適當的計劃,可能或可能不適合以下各種值:b,如'%A','%','A'等。

相似問題可以用一個等式謂詞來應用,但是可能導致的基數範圍更容易根據列統計或存在唯一約束來估計,例如樂。

所以,我個人不會開始使用LIKE作爲=的替代品。優化器有時很容易被愚弄。

5

查看兩者的EXPLAIN PLAN。他們生成相同的執行計劃,所以對於數據庫來說,它們是相同的。

你會用=來檢驗相等性,而不是相似性。如果您也在控制比較值,那麼它沒有太大區別。如果這是由用戶提交的,那麼'apple'和'apple%'會給你很多不同的結果。

+0

對於非常大的表,LIKE測試和=之間可能會有明顯的性能差異,即使該計劃是相同的。但最好測試一下。 – 2008-09-25 17:00:22

+0

是的,如果你使用綁定變量,你應該如此,優化器並不知道你要傳遞給它的東西。所以,它不一定是最好的,因爲只有一面有通配符。 (當然,Oracle可能已經解決了這個問題)。 – 2008-09-30 13:08:00

1

你試過了嗎?測試是唯一可以確定的方法。

另外,這些語句都不能確定返回相同的行。試用:

insert into some_table (some_field) values ('some_value'); 
insert into some_table (some_fieled) values ('1some_value2'); 
insert into some_table (some_field) values ('some1value'); 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE '%some_value%'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD = 'some_value'; 

SELECT * FROM SOME_TABLE WHERE SOME_FIELD LIKE 'some_value'; 

在清晰度方面,避免微妙的錯誤,這是最好的,除非你需要它的通配符功能,從來沒有使用LIKE。 (顯然,在做臨時查詢時,它可能是正常的。)

1

LIKE'%WHATEVER%'必須執行完整的索引掃描。

如果沒有百分比,那麼它就像一個等於。

如果%在一端,那麼該索引可以是範圍掃描。

我不確定優化器如何處理綁定字段。

3

如果是這樣,我的問題是,爲什麼 曾經使用「=」?

更好的問題:如果這是真的,爲什麼使用「LIKE」來檢驗相等性?您可以保存按下Shift鍵,每個閱讀腳本的人都會感到困惑。

1

like如果您沒有像$%等字符,則形式上是相同的,因此發現它具有相同的成本並不是一個大驚喜。

我發現David Aldridge回答很有趣,因爲您的應用程序應該使用綁定變量。使用like '%foobar',您無法使用索引中的排序。如果查詢是預編譯的,將導致更多的索引或表格全部掃描。

而且,我覺得很危險的,因爲它可以導致SQL注入和奇怪的錯誤(例如,如果有一個名爲john的用戶,黑客可以創建一個名爲'joh$'用戶嘗試登錄)

爲什麼冒着風險? '='更清晰,並沒有這些問題。

相關問題