MySQL 查询随机滞后

2022-08-30 12:04:56

我有一个如下所示的查询:

SELECT id FROM user WHERE id='47'

使用分析数据时,将对此查询编制索引,并且此查询的读取始终很快,如下所示。

SET profiling = 1;
SHOW PROFILES;

查询始终在大约 0.0002 秒内执行。

但是,如果我从PHP端分析查询,如下所示:

$current = microtime(true);
$data = $conn->query($full_query);
$elapsed = microtime(true) - $current;

然后,偶尔,这些查询中的1个可能需要大约0.2秒。但是,在我的测试脚本中,我有代码来测试这一点,该代码使用SET分析 = 1来分析查询;即使 PHP 通过 PDO 的往返行程可能是 0.2 秒,查询时间仍然是 0.0002。

我知道或知道的不会导致问题的事情:

  1. 查询速度不慢。当我从相同的查询运行中查看相同的查询时,在PHP中分析并使用SET PROFILING进行分析时,查询总是很快,并且永远不会记录在慢速查询日志中,即使它显示从PHP端花费.2秒。
  2. 这与跳过名称解析无关 - 这是不一致的,我已经打开了跳过名称解析
  3. 这与查询缓存无关,行为存在于两者中
  4. 即使在从缓存中发出的查询上也会发生此行为。
  5. 该查询实际上并没有选择ID,但我使用此查询进行测试,以表明它不是磁盘访问问题,因为该字段肯定已编入索引。
  6. 此表只有 10-20 兆元,索引为 1 兆兆。机器显示的负载非常小,innodb没有使用其所有缓冲区。
  7. 这是针对一个表进行测试的,该表除了我的测试查询之外没有其他活动。

有没有人对要检查的其他内容有任何想法?在我看来,这是一个网络问题,但我需要能够看到它并找到问题来修复它,而且我没有足够的地方来检查下一步。有什么想法吗?


答案 1

我会分析机器。

您说这种情况每 50 次发生约 1 次,并且每个查询的基准测试为 0.2 秒。您应该能够将顶部放在屏幕中,然后在PHP中运行查询循环以对RDBMS进行负载测试并收集性能统计信息。

您可能需要运行超过10秒,因为您的“50个中的1个”统计信息可能基于手动运行的各个查询 - 基于我在您的描述中读到的内容。尝试 30 秒和 90 秒负载测试。50 * 0.2 =

在此期间,请观看您的过程屏幕。按 CPU 对它进行排序,方法是按 。每次按“P”时,它都会更改进程CPU消耗的排序顺序,因此请确保您在顶部具有最消耗。(按内存使用情况按排序。请查看手册页了解详细信息)topPM

查找在负载测试期间冒泡到顶部的任何内容。你应该看到一些东西跳得更高 - 无论多么短暂。
(请注意,这样的过程可能不会到达列表的顶部 - 它不需要,但仍然可能引入足够的磁盘负载或其他活动来滞后MySQL服务器)


答案 2

我注意到我的系统上有同样的现象。通常需要一毫秒的查询将突然需要1-2秒。我的所有情况都是简单的,单表 INSERT/UPDATE/REPLACE 语句---不在任何 SELECT 上。没有负载,锁定或线程积聚是显而易见的。

我怀疑这是由于清除脏页,刷新对磁盘的更改或某些隐藏的互斥体,但我还没有缩小范围。

也排除了

  1. 服务器负载 -- 与高无关

  2. load Engine -- 与 InnoDB/MyISAM/Memory MySQL Query 一起发生

  3. 缓存 -- 无论它是打开还是关闭,都会发生

  4. 日志轮换 -- 事件中没有相关性


推荐