1

我知道使用 REGEXP 有其缺点,尤其是在查询时间方面,但是,除了使用它,我别无选择。

问题是,查询可能需要超过 5 分钟才能运行,具体取决于使用了多少搜索词。

我的任务是获取一个搜索词,并找到确切的搜索词,以及该词的一些变体,例如复数,以“ing”结尾,或者搜索词后跟任何标点符号,但不是单词片段,所以“ car" 不应匹配 "carbine" 或 "scar"。可以使用无限数量的搜索词,但是当数字开始超过 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,因此唯一可以使用的索引是字段,尽管在and字段date上设置了索引。我曾考虑将我的搜索引擎改为使用 Solr 之类的东西,但即便如此,考虑到搜索所需的特殊性,我认为它不会起作用。namevenue

非常感谢任何建议。谢谢

4

1 回答 1

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:]]"[[:>:]]匹配。

于 2013-05-14T04:01:30.720 回答