使用 75% 的总时间查询“创建排序索引”的 MySQL 配置文件

Jus*_*tin 16 mysql profiler

我们试图弄清楚如何优化查询(大约需要 100 毫秒),并运行我们看到Creating Sort Index使用75%的总时间的配置文件。首先,究竟是什么影响了创建排序索引?是磁盘/io吗?

其次,我们可以对查询本身进行任何优化吗?

SELECT r.`id`, 
       r.name, 
       r.public_uri, 
       rv.version, 
       rv.interpreter, 
       rv.notes, 
       rv.content, 
       r.added, 
       r.added_by, 
       r.modified, 
       r.modified_by, 
       r.public, 
       r.public_by
  FROM recipe_heads rh, 
       recipes r, 
       recipe_versions rv
 WHERE rh.recipe = r.`id` 
   AND rh.recipe_version = rv.`id` 
   AND r.`id` = rv.recipe
ORDER BY r.added DESC
Run Code Online (Sandbox Code Playgroud)

解释: 截屏

小智 7

“创建排序索引”是数据库根据“order by”子句计算返回值的顺序。这里的主要限制因素是可用的 CPU/CPU 速度和内存带宽。在数据已经全部在内存中之前,不会进行排序,至少对于这么小的查询。如果您分析查询,您是否看到任何资源的等待?

至于使这个查询更快,您可以考虑在“r. added”上添加一个索引,因为根据您的解释,它看起来不像是一个索引。


Cha*_*dni 7

我们在处理大量查询时遇到了类似的问题。根据 400M 行的 DB 负载,查询通常会运行数小时(最多 7-8 小时)。但是,我们的目标是实现分组结果,例如按 1、2、3 从表组中选择 col1、col2、col3、count(1)、count(distinct col4)。

潜在的问题与您的相同,因为在这两种情况下,DB 都会在内部对结果进行排序(排序)。

  • 创建排序索引的工作原理。在 mysql 网站上,它说“线程正在处理使用内部临时表解析的 SELECT”。根据我的算法理解,系统很可能将数据拆分成块,从磁盘一个一个地读取这些块,对单个块进行排序,放回一些临时磁盘空间等等。系统对所有块执行此操作并最终执行归并排序。这涉及广泛的读/写。

一个可能的解决方案是增加 DB 的内存(以便它可以创建可以保留在内存中的更大的块),或者如果您在其他地方有更大的内存,您可以通过从 DB 流来编程解决方案。这可以在 nlogn 时间内实现。

以编程方式,我可以将时间从平均 2 小时减少到一致的 7.5 分钟。