Mysql使用通配符提高搜索性能(%%)

时间:2011-05-05 23:14:58

标签: mysql sql indexing query-optimization

以下是我用于通过电子邮件搜索某人的查询

  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

在“电子邮件”上添加索引会加快查询速度吗?

6 个答案:

答案 0 :(得分:17)

不,因为当你有一个领先的通配符时,MySQL将无法使用索引。如果您将LIKE更改为'f%',则可以使用索引。

答案 1 :(得分:7)

不,Mysql将不使用索引,因为LIKE参数(%f%)以通配符%开头。 如果以常量开头,则使用索引。

更多信息:7.5.3. How MySQL Uses Indexes

答案 2 :(得分:5)

通配符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技术,比如Sphinx。

答案 3 :(得分:4)

在我的帖子中,我详细介绍了一种技术,可让您使用索引LIKE进行快速 %infix%搜索 ,以一些额外的存储为代价:

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

只要字符串相对较小,存储要求通常是可以接受的。

据谷歌称,平均电子邮件地址长度为25个字符。这会使您所需的存储空间平均增加12.5,并为您提供快速索引搜索。 (请参阅我的帖子进行计算。)

从我的角度来看,如果您要存储10'000个电子邮件地址,那么您应该存储(相当于)大约100'000个电子邮件地址。如果这是允许您使用索引所需的,那似乎是可接受的权衡。通常,磁盘空间很便宜,而非索引搜索则无法承受。

如果您选择采用此方法,我建议您将电子邮件地址的输入长度限制为64个字符。那些这种长度的罕见(或攻击者)电子邮件地址将需要最多32倍的常规存储空间。这给你:

  1. 防止攻击者试图淹没您的数据库,因为这些数据仍然不是非常令人印象深刻。
  2. 期望大多数电子邮件地址都不是这个长度。
  3. 如果您认为64字符的要求过于苛刻,请使用255代替最差情况下的存储增加因子127.5。荒谬?有可能。可能性有多大?不,快?非常

答案 4 :(得分: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

答案 5 :(得分:-3)

伙计我很高兴人类大脑有时如此聪明,以至于它可以克服明显不可抗拒的问题。我知道如何智取mysql并启用索引搜索,即使从左侧搜索外卡。只需创建列的反转列(使其成为索引),反转搜索字符串,并使用右侧带有索引支持的通配符。

所以如果你有db word" slibro"并且你想要搜索"%libro",创建的反向列将包含" orbils"并且搜索将是" orbil%"。

如果您喜欢我的解决方案,请查看我的个人资料并向我发送一些BTC,谢谢:)

PS:但是没有解决方案如何快速完整的通配符搜索"%x%"虽然:)。