2017-06-21 49 views
0

目前,我有這個疑問如何優化與通配符查詢WHERE與LIMIT子句

SELECT field1 FROM table1 
WHERE field1 LIKE '%foo%' 
LIMIT 20 

它是更有效的有以下查詢?

SELECT field1 FROM table1 
WHERE 
field1 LIKE 'foo' OR 
field1 LIKE 'foo%' OR 
field1 LIKE '%foo%' 
LIMIT 20 

版本的SQL(對不起,我應該早點mentionned)一個共享的主機

的MySQL 5.5 InnoDB引擎。有了這個配置我不能使用FULLTEXT指數(全文索引可從MySQL的InnoDB的V5.6)

MY具體目的

我需要找到20條記錄包含。大多數時候,這個詞將匹配在場上完全值,即見下表:

| **field1** | **search** | 
| record1 | foo  | 
| record2 | fooziness | 
| record3 | other1 | 
| record4 | foo  | 
| record5 | other2 | 
|  ...  |  ...  | 

我知道'word' OR 'word%'使用INDEX而最後'%word%'沒有。

將查詢優化器首先嚐試找到'word' OR 'word%'記錄並保存低效搜索'%word%'如果20 'word'被發現?

+1

爲什麼你不測試它並檢查解釋計劃? [** MySQL **](http://dba.stackexchange.com/questions/15371/how-do-i-get-the-execution-plan-for-a-view) –

+1

btw你的第二個查詢不是好的。您必須編寫'field1 ='foo'或field1 LIKE'foo%'或field1 LIKE'%foo%' –

+0

我還沒有足夠的數據在表中:-) – gentleboy

回答

3

這對您來說測試要比我們回答容易得多 - 尤其是因爲實際查詢可能比您顯示的要複雜得多。

但是......

按照manual,限制可以優化查詢,但主要是通過訂單時。這是有道理的,因爲很可能會有多個「where」子句和限制子句不一定知道哪些子句受限制子句的影響。

我已經通過執行以下操作以類似的查詢被騙:

(SELECT field1, 1 as quality FROM table1 
    WHERE field1 = 'foo' 
) union 
(SELECT field1, 2 as quality FROM table1 
    WHERE field1 LIKE 'foo%' 
) union 
(SELECT field1, 3 as quality FROM table1 
    WHERE field1 LIKE '%foo%' 
)  
order by quality 
LIMIT 20 

這是可讀的要少得多,但沒有欺騙優化器放棄查詢,一旦發現了20條記錄。不知道這是否可行。

當然,如果性能對您很重要,那麼使用MySQL Full text searching要快得多,而且要脆弱得多。

+0

你是對的,查詢對於許多聯接而言更復雜。不能使用全文索引作爲與innoDB的MySQL 5.5(抱歉沒有提到)。 – gentleboy

+0

我認爲一個簡單的改變就可以做到這一點,但它似乎更復雜。我測試過,現在看來你有唯一的解決方案。我想我必須儘快重寫我的查詢。 – gentleboy

+0

我添加了parens,這樣'ORDER BY'和'LIMIT'將應用於'UNION',而不是最後一個'SELECT'。 –