2011-05-05 72 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最坏情况的存储增长的因素。荒谬?有可能。可能性有多大?没有快速?非常。