MySQL简单插入查询在“查询结束”步骤上很慢

Posted

技术标签:

【中文标题】MySQL简单插入查询在“查询结束”步骤上很慢【英文标题】:MySQL simple insert query slow on "query end" step 【发布时间】:2013-08-22 01:14:39 【问题描述】:

我正在尝试虚拟化我的 percona 服务器 5.5.32-31.0 并且看到一些奇怪的东西。在虚拟化盒子上,插入(实际上是所有)查询很慢,但配置文件的“查询结束”步骤会缩短响应时间。

让我退后一步,这是我的测试表:

CREATE TABLE `mysql_io_test` (
  `id` int(11) NOT NULL,
  `time_diff` char(8) COLLATE utf8mb4_unicode_ci NOT NULL,
  `data` char(100) COLLATE utf8mb4_unicode_ci NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

运行这个:

set profiling = 1;
insert into util.mysql_io_test select 999, '99:99:99', 'ABCDEFGHIJ';
set profiling = 0;

我明白了:

starting, 0.000031
checking permissions, 0.000005
Opening tables, 0.000530
System lock, 0.000008
init, 0.000008
optimizing, 0.000002
executing, 0.000095
end, 0.000005
query end, 0.067226
closing tables, 0.000013
freeing items, 0.000039
logging slow query, 0.000002
cleaning up, 0.000005

在未虚拟化的盒子上(使用较旧的数据库:v5.5.27-28.1)我得到更合理的:

starting, 0.000039
checking permissions, 0.000004
Opening tables, 0.000013
System lock, 0.000009
init, 0.000008
optimizing, 0.000002
executing, 0.000038
end, 0.000003
query end, 0.000143
closing tables, 0.000008
freeing items, 0.000018
logging slow query, 0.000001
cleaning up, 0.000002

我对每个步骤的真正意义并不是非常熟悉,但我真的不知道为什么“查询结束”会很慢。手册 (http://dev.mysql.com/doc/refman/5.5/en/general-thread-states.html) 没有提供更多信息。明天我会尝试回滚到旧版本并深入研究代码,但我想有人可能以前见过这个,也许可以为我揭开这个谜团。

其他一些可能有用的东西:

VM 运行在与旧机器一样强大的机器上,两者都是中等范围 目前还有 6 个其他 VM 在盒子上运行 此服务器通常比旧服务器慢 新服务器上的一些大型负载测试非常糟糕,但最近的负载测试实际上比旧服务器快。所以我不能说这个“查询结束”问题一直都在发生;尽管自上次大型测试以来配置已更改。

【问题讨论】:

如果百分之六秒对于提交到磁盘的写入的要求非常“慢”,您将需要详细说明存储配置(设置、操作系统、缓冲区、硬件)在每种情况下使用。在那,这个问题可能属于Database Administrators而不是SO。坦率地说,我很惊讶您关心如此微小的差异:感觉就像是毫无意义的微优化。记住 Knuth 的格言“过早的优化是万恶之源”。 在旧服务器上我每秒可以插入大约 1000 行,而在新服务器上只插入大约 15 行,这似乎不合适。我认为这不是存储配置问题,因为使用 fio 直接进行硬盘测试会在 VM 中产生与未虚拟化机器上相同的 i/o。大多数情况下,这只是让我失望的奇怪步骤。如果它正在发送数据或类似的东西,它会更清楚它实际上花时间在做什么。 【参考方案1】:

对于遇到此问题的其他任何人,我想我已经找到了一些问题。我已将 innodb_flush_method 从常规框上的 ALL_O_DIRECT 更改为 VM 上的 O_DIRECT,因为 mysql 发出此警告:

kernel: EXT4-fs (vdb1): Unaligned AIO/DIO on inode 17565314 by mysqld; performance will be poor.

恢复到 ALL_O_DIRECT 会使该警告再次开始出现 - 但我的性能在“查询结束”步骤中提高了 100 倍,所以我现在将继续使用它。

我希望这可以帮助遇到同样问题的其他人。

【讨论】:

以上是关于MySQL简单插入查询在“查询结束”步骤上很慢的主要内容,如果未能解决你的问题,请参考以下文章

mysql数据库插入数据很慢

在 MySQL 5.5 的“查询结束”中运行更长时间的微小插入查询,过去在 5.0 中啥都没有

MySQL查询在大表上很慢

带有子查询的 CTE 查询在小型索引表上很慢;如何在 MySQL 上进行优化?

perl dbi mysql 向表中插入数据速度很慢

为啥 count(*) 查询在某些表上很慢,而在其他表上却没有?