我写了一个搜索查询,搜索相似的名字。它适用于标签的 Power Set ,并按相似性进行排序。例如,如果搜索文本为:shakespeare tragedy hamlet
生成的SQL是:
SELECT DISTINCT id FROM (
(SELECT * FROM books
WHERE name LIKE '%shakespeare%'
AND name LIKE '%tragedy%'
AND name LIKE '%hamlet%' limit 10)
UNION
(SELECT * FROM books
WHERE name LIKE '%shakespeare%'
AND name LIKE '%tragedy%' limit 10)
UNION
(SELECT * FROM books
WHERE name LIKE '%shakespeare%'
AND name LIKE '%hamlet%' limit 10)
UNION
(SELECT * FROM books
WHERE name LIKE '%tragedy%'
AND name LIKE '%hamlet%' limit 10)
UNION
(SELECT * FROM books WHERE name LIKE '%shakespeare%' limit 10)
UNION
(SELECT * FROM books WHERE name LIKE '%tragedy%' limit 10)
UNION
(SELECT * FROM books WHERE name LIKE '%hamlet%' limit 10)
) limit 10
有两个问题:
Power Set会在我的查询中创建2^tags - 1
个联合,这意味着如果某个人想要精确并且使用6个标签,它将是63个联合并且它使我的查询慢得多。
如果第一个联合返回10行,则其他联合没用。
有没有办法优化此查询?
答案 0 :(得分:0)
我们可以获得名称与过去标签类似的所有boosk,并根据相似性添加自定义ORDER BY。如果name包含标签+1,如果不是0.如果name包含所有3个标签,如果只有一个和,则sum为3。
SELECT DISTINCT id
FROM books
where name LIKE '%shakespeare%'
OR name LIKE '%tragedy%'
OR name LIKE '%hamlet%'
ORDER BY IF(INSTR(name, 'shakespeare')>0,1,0)+
IF(INSTR(name, 'tragedy')>0,1,0)+
IF(INSTR(name, 'hamlet')>0,1,0) DESC
LIMIT 10
更新:ORDER BY可以基于总和或只是逗号
答案 1 :(得分:0)
如果切换到FULLTEXT
索引并使用
MATCH(name) AGAINST('shakespeare tragedy hamlet')
您可以获得一个合理的订购,并更快地运行 lot 。
如果你想坚持shakespeare
在字符串中,但其他人是可选的,那么效果更好:'+shakespeare tragedy hamlet'
。
警告:FULLTEXT
有两个好处和局限。