据我所知,使用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
字段,尽管索引是在name
和venue
字段上设置的。
我已经考虑过将我的搜索引擎改为使用像Solr这样的东西,但即便如此,考虑到搜索所需的特殊性,我认为它不会起作用。
非常感谢任何建议。 感谢
答案 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:]]"
,因为[[:>:]]
会在字词和标点符号之间匹配。