提高MySQL全文搜索查询的性能

ale*_*oid 4 mysql sql full-text-search

我有以下MySQL查询:

SELECT p.*, MATCH (p.description) AGAINST ('random text that you can use in sample web pages or typography samples') AS score 
FROM posts p 
WHERE p.post_id <> 23 
AND MATCH (p.description) AGAINST ('random text that you can use in sample web pages or typography samples') > 0 
ORDER BY score DESC LIMIT 1
Run Code Online (Sandbox Code Playgroud)

有108,000行,需要大约200ms.拥有265,000行,需要约500毫秒.

在性能测试(约80个并发用户)下,它显示~18秒的平均延迟.

有没有办法提高此查询的性能?

EXPLAIN OUTPUT:

在此输入图像描述

更新

我们添加了一个新镜像MyISAM表post_id, descriptionposts通过触发器将其与表同步.现在,在这个新的MyISAM表上进行全文搜索工作约400ms(具有相同的性能负载,其中InnoDB显示~18秒 ......这是一个巨大的性能提升)看起来MyISAM在MySQL中的全文比InnoDB快得多.你能解释一下吗?

MySQL分析器结果:

AWS RDS db.t2.small实例上测试

原始InnoDB posts表:

在此输入图像描述

带有post_id的MyISAM镜像表,仅供说明:

在此输入图像描述

Bjo*_*ern 5

以下是一些提示,以便通过InnoDB最大限度地提高查询速度:

  1. 避免多余的排序.由于InnoDB已根据排名对结果进行了排序.MySQL查询处理层不需要排序以获得最佳匹配结果.

  2. 避免逐行提取以获得匹配计数.InnoDB提供所有匹配的记录.所有不在结果列表中的人都应该排名为0,不需要检索.InnoDB拥有总计匹配记录数.无需重述.

  3. 覆盖索引扫描.InnoDB结果始终包含匹配记录的文档ID及其排名.因此,如果只需要文档ID和排名,则无需转到用户表来获取记录本身.

  4. 尽早缩小搜索结果,减少用户表访问.如果用户想要获得前N个匹配记录,我们不需要从用户表中获取所有匹配的记录.我们应该能够首先选择TOP N匹配的DOC ID,然后只获取具有这些Doc ID的相应记录.

我不认为你只能查看查询本身就不会那么快,也许尝试删除ORDER BY部分以避免不必要的排序.为了深入研究这个问题,可以使用MySQLs inbuild profiler对查询进行分析.

除此之外,您可以查看MySQL服务器的配置.看一下MySQL手册的这一章,它包含了一些关于如何根据需要调整全文索引的好信息.

如果您已经最大化了MySQL服务器配置的功能,那么请考虑查看硬件本身 - 有时甚至是丢失的成本解决方案,例如将表移动到另一个,更快的硬盘驱动器可以创建奇迹.