我在我的网站上实施了搜索,它运行以下查询:
SELECT COUNT(mov_id) AS total_things
FROM content
WHERE con_status = 1 AND con_incomplete = 0 AND con_type = 1
AND ((con_title) LIKE ('%search keyword%')
OR soundex(con_title) LIKE soundex('search keyword')
OR MATCH (con_title) AGAINST ('search keyword'));
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-------------+
| 1 | SIMPLE | movies | ref | con_type | con_type | 12 | const,const,const | 11804 | Using where |
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-------------+
SELECT
con_id,
con_title,
con_desc,
MATCH (con_title) AGAINST ('search keyword') AS relevancy
FROM content
WHERE con_status = 1 AND con_incomplete = 0 AND con_type = 1
AND ((con_title) LIKE ('%search keyword%')
OR soundex(con_title) LIKE soundex('search keyword')
OR MATCH (con_title) AGAINST ('search keyword'))
ORDER BY relevancy DESC
LIMIT 0, 24;
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-----------------------------+
| 1 | SIMPLE | movies | ref | con_type | con_type | 12 | const,const,const | 11803 | Using where; Using filesort |
+----+-------------+--------+------+---------------+----------+---------+-------------------+-------+-----------------------------+
这基本上就像一个贫民窟“模糊搜索”,以忽略人们可能犯的错别字。
不幸的是,它非常慢(即使我删除了soundex()或FULLTEXT搜索。如何在这种情况下提高搜索速度?
答案 0 :(得分:2)
伤害的WHERE子句部分是%
之后的第一个LIKE
。为了加快速度,您可以将关键字规范化,将它们移到单独的表中:
table moviekeywords: movieid, keyword
table movies: movieid, ...
这允许您使用moviekeywords
条件或至少=
搜索like 'humphrey%'
表。两种变体都可以用索引快速制作。
答案 1 :(得分:0)
只要您继续使用soundex和LIKE(%nnn%),您将运行所有中间结果的完整扫描。为了说明这一点:如果省略了其他谓词(在con_status,con_incomplete和con_type列上),您将始终运行全表扫描。
我建议删除或缩减模糊谓词。例如,只运行LIKE('nnn%')将比%nnn%快得多(如果该列被索引),但当然搜索结果不会模糊。也许使soundex成为一种并不总能运行的高级搜索选项。
如果您无法在任何问题上妥协,那么至少要确保您的con_status,con_incomplete和con_type列都已编入索引。
答案 2 :(得分:0)
如果原始更严格的查询中的COUNT没有返回任何结果,那么我将“模糊搜索”作为后备选项。到目前为止,我的结果使用
非常快 SOUNDS LIKE ('blah')
答案 3 :(得分:0)
再次考虑Andomar的解决方案 - 大多数关键字搜索允许您指定多个关键字。您不能使用当前查询执行此操作。 “终结者”没有问题 - 为此,你只需添加一个关键词“终结者”。
使用关键字列的索引,它会很快。
答案 4 :(得分:0)
所以看起来你只有大约15,000行。如果你不希望你的表增长超过十万条左右,也许你应该将所有标题保留在内存中并避免访问数据库,直到你知道你想要哪些条目。
也就是说,在启动时和定期间隔,只查询数据库中的所有标题,将每个标题分成单词,并保持单词到行键的映射。这应该占用不到1MB的内存,访问它应该非常快,最重要的是你可以添加你喜欢的任何模糊匹配或启发式评分机制(不修改你的模式)。
只是一个想法。