2011-05-05 32 views
9

下面是我用電子郵件搜索一個人的查詢Mysql的改善與通配符(%%)的搜索性能

SELECT * 
    FROM phppos_customers 
    JOIN phppos_people ON phppos_customers.person_id = phppos_people.person_id 
    WHERE deleted = 0 
    AND email LIKE '%f%' 
ORDER BY email ASC 

將添加的「電子郵件」加快查詢索引?

+0

[解釋](http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning)可能有助於理解爲什麼它不起作用。 – 2011-05-12 05:42:32

+1

[**這個答案**](http://stackoverflow.com/a/22531268/793309)顯示了一個很好的技術 - 索引所有後綴 - 可以使這種查詢執行得很好,但代價是一些額外的編碼和更大的存儲需求。 – antinome 2014-12-11 15:26:58

回答

14

沒有,因爲MySQL將無法使用索引,當你有一個領先的通配符。如果您將LIKE更改爲'f%',那麼它將能夠使用索引。

8

不,Mysql將不會使用索引,因爲LIKE參數(%f%)以通配符%開頭。 如果它以一個常量開始,將使用索引。

更多信息:7.5.3. How MySQL Uses Indexes

1

LIKE就像所有人都說的那樣(關於開頭的%),您將無法使用它加快速度,但您可以通過首先篩選人員後加入,從而加以改進。

SELECT * 
    FROM (SELECT * 
      FROM `phppos_customers` 
     WHERE `deleted` = 0 
      AND `email` LIKE '%f%') `t_customers` 
    JOIN `phppos_people` ON `t_customers`.`person_id`=`phppos_people`.`person_id` 
ORDER BY `email` asc 
+0

在派生表/內嵌視圖中使用帶有左側通配符的'LIKE'仍然不會使用索引... – 2011-05-05 23:48:25

+0

我從來沒有說過它會... – 2011-05-05 23:53:21

+0

OP會特別詢問索引的使用...我' m傾向於downvote,因爲你知道你不提供任何有價值的問題... – 2011-05-05 23:55:03

4

通配符一個LIKE操作的左側確保的指標,如果一個在email列中存在時,不能使用。

全文搜索(FTS)是通過SQL在文本內查找字符串的首選語法。 MySQL has native FTS functionality, using the MATCH/AGAINST syntax (Requires the table to use the MyISAM engine for v.5.5 and below. InnoDB FTS supported on v.5.6+)

SELECT c.*, p.* 
    FROM PHPPOS_CUSTOMERS c 
    JOIN PHPPOS_PEOPLE p ON p.person_id = c..person_id 
    WHERE deleted = 0 
    AND MATCH(email) AGAINST('f') 
ORDER BY email 

但有第三方FTS技術,如斯芬克斯。

+0

我詳細介紹了FULLTEXT並在此討論了一些關於Sphynx的內容:http://stackoverflow.com/questions/3338889/how-to-find-similar-results-and-sort-by-similarity/3339034#3339034 – 2011-05-05 23:43:14

+0

從MySQL InnoDB表格現在提供5.6 FTS功能。 – blo0p3r 2015-04-07 12:56:41

3

在這裏我的文章中,我描述,在細節,技術,使您可以使用索引LIKE快速%infix%搜索,在一些額外的存儲成本:

https://stackoverflow.com/a/22531268/543814

只要字符串相對較小,存儲要求通常是可以接受的。

根據谷歌的說法,平均電子郵件地址是25個字符。這將平均需要的存儲空間增加了一個因子12.5,併爲您提供快速索引搜索。 (看我的帖子的計算。)

從我的角度來看,如果你正在存儲10'000個電子郵件地址,你應該很好地存儲(相當於)大約100'000個電子郵件地址。如果這是允許您使用索引所需要的,那麼這似乎是一個可接受的折衷。通常,磁盤空間很便宜,而非索引搜索則無法承受。

如果您選擇採用此方法,我建議您將電子郵件地址的輸入長度限制爲64個字符。那些罕見的(或攻擊者)這種長度的電子郵件地址將需要通常存儲的32倍。這給你:

  1. 防止攻擊者試圖淹沒你的數據庫,因爲這些數據仍然不是很多。
  2. 無論如何,大多數電子郵件地址都不是這個長度的期望。

如果考慮64字符過於苛刻的要求,使用255而是爲127.5最壞情況的存儲增長的因素。荒謬?有可能。可能性有多大?沒有快速?非常。