我正在使用此查询对MySQL数据库执行全文搜索:
SELECT DISTINCT
questions.id,
questions.uniquecode,
questions.spam,
questions.questiondate,
questions.userid,
questions.description,
users.login AS username,
questions.questiontext,
questions.totalvotes,
MATCH(questions.questiontext, questions.uniquecode)
AGAINST ('rock guitarist chick*' IN BOOLEAN MODE) AS relevance
FROM questions
LEFT JOIN users ON questions.userid = users.id
LEFT JOIN answer_mapping ON questions.id = answer_mapping.questionid
LEFT JOIN answers ON answer_mapping.answerid = answers.id
LEFT JOIN tagmapping ON questions.id = tagmapping.questionid
LEFT JOIN tags ON tagmapping.tagid = tags.id
WHERE questions.spam < 10
AND
(
MATCH(questions.questiontext, questions.uniquecode)
AGAINST ('rock guitarist chick*' IN BOOLEAN MODE)
OR MATCH(answers.answertext) AGAINST ('rock guitarist chick*' IN BOOLEAN MODE)
OR MATCH (tags.tag) AGAINST ('rock guitarist chick*' IN BOOLEAN MODE)
) GROUP BY questions.id ORDER BY relevance DESC
结果非常相关,但是搜索速度非常慢,并且随着表的增长速度越来越慢。
表格统计:
问题-400条记录
索引
主树-ID
BTree-唯一代码
btree-问题日期
btree-用户ID
全文-问题文本
全文-唯一代码
答案-3635条记录
索引
主-树-id
btree-答案日期
BTree-问题ID
全文-答案文本
答案映射-4228条记录
索引
主-树-id
btree-答案id
BTree-问题ID
btree-用户ID
标签-1847条记录
索引
主-树-id
BTree-标记
全文-标记
标记映射-3389条记录
索引
主-树-id
btree-标记id
BTree-问题ID
无论出于什么原因,当我删除标记映射和标记连接时,搜索速度都会大大提高。
关于如何加快查询速度,你有什么建议吗?
提前谢谢!
最佳答案
好吧,你可以把你的连接合并到一个缓存视图或者额外的表或者其他什么东西中。使查询缓存处于活动状态,并将连接定义为select,以便可以缓存它。确保有足够的内存等,但这不应该是瓶颈。很可能是因为…只有400张唱片?没什么…已经很慢了?因为剩下的看起来不错。您正在运行哪种硬件/配置?
但是,我认为这是错误的做法。mysql不是为这个而设计的。事实上,全文功能仅限于myisam。
您应该考虑使用lucene/solr使用dismax请求处理程序。
它应该在大约50ms-100ms的时间内为您提供良好的结果,索引大约为十万个文档。在某个时刻,你可以切分它,这样记录的数量实际上是无限的。
另外,你有更好的选择,可以取得更好的结果。例如,对更新的文档进行模糊匹配或赋予更多的权重,或者使用比标题更相关的标记,执行查询后分析、faceting等…