MySQL使用REGEXP导致查询时间过长

时间:2013-05-14 03:25:27

标签: mysql regex

据我所知,使用REGEXP有其缺点,特别是在查询时间方面,但是除了使用它之外我别无选择。

问题是,查询可能需要5分钟才能运行,具体取决于使用的搜索字词数。

我的任务是找一个搜索词,找到确切的搜索词,以及单词的某些变体,例如复数,以'ing'结尾,或搜索词后跟任何标点符号,但不是单词的片段,所以“汽车”不应该匹配“卡宾枪”或“疤痕”。 可以使用无限数量的搜索词,但是当数字开始超过6时,它将变得无法忍受。

以下是我的查询示例:

SELECT `id` FROM `table` WHERE (( 
    `name`  REGEXP "[[:<:]]sesame street[[:>:]]" OR
    `name`  REGEXP "sesame street[[:punct:]]" OR
    `name`  REGEXP "[[:<:]]sesame street.?ing[[:>:]]" OR
    `name`  REGEXP "[[:<:]]sesame street.?s[[:>:]]"
) OR ( 
    `venue`  REGEXP "[[:<:]]disney[[:>:]]" OR
    `venue`  REGEXP "disney[[:punct:]]" OR
    `venue`  REGEXP "[[:<:]]disney.?ing[[:>:]]" OR
    `venue`  REGEXP "[[:<:]]disney.?s[[:>:]]"
 )) 
 AND `name` NOT LIKE "% tantrum %" 
 AND `name` NOT LIKE "% stepkids %" 
 AND `date` >= CURDATE() 
 ORDER BY `date` ASC;

查询使用单个表,因此没有表连接问题。

单个查询可以包含30个不同的关键字,可以包含或排除,然后是这些搜索字词的变体,因此每个字词可以创建5个不同的条件。 由于查询使用REGEXP,因此可以使用的唯一索引是date字段,尽管索引是在namevenue字段上设置的。 我已经考虑过将我的搜索引擎改为使用像Solr这样的东西,但即便如此,考虑到搜索所需的特殊性,我认为它不会起作用。

非常感谢任何建议。 感谢

1 个答案:

答案 0 :(得分:0)

通过使用每个搜索字词的单个表达式而不是现在的四个表达式,您可能可以实现一些改进(最多4倍)。

而不是使用:

`venue`  REGEXP "[[:<:]]disney[[:>:]]" OR
`venue`  REGEXP "disney[[:punct:]]" OR
`venue`  REGEXP "[[:<:]]disney.?ing[[:>:]]" OR
`venue`  REGEXP "[[:<:]]disney.?s[[:>:]]"

你可以写:

`venue`  REGEXP "[[:<:]]disney(.?(s|ing))?[[:>:]]"

您不需要"disney[[:punct:]]",因为[[:>:]]会在字词和标点符号之间匹配。