繁体   English   中英

当有少量索引时,为什么MySQL InnoDB在大型表上插入/更新会变得非常慢?

[英]Why do MySQL InnoDB inserts / updates on large tables get very slow when there are a few indexes?

我们有一系列有机增长到数百万行的表,在生产中进行插入或更新可能需要长达两秒钟。 但是,如果我转储表并从转储查询重新创建它是快速的。

我们通过创建一个副本来重建其中一个表,重建索引然后执行重命名切换并复制任何新行,这是因为该表只被附加到。 这样做可以快速插入和更新闪存。

我的问题:

为什么插入会随着时间的推移变慢? 为什么重新创建表并进行导入修复? 有没有办法可以重建索引而不锁定表更新?

这听起来像是

  • 索引不平衡随着时间的推移
  • 磁盘碎片
  • 内部innodb数据文件碎片

您可以尝试analyze table foo不带锁的analyze table foo ,只需几次索引潜水并花费几秒钟。

如果这不能解决问题,您可以使用

mysql> SET PROFILING=1;
mysql> INSERT INTO foo ($testdata);
mysql> show profile for QUERY 1;

你应该看到大部分时间花在哪里。

显然,当以PK命令完成插入时,innodb表现更好,这是你的情况吗?

InnoDB性能严重依赖于RAM。 如果索引不适合RAM,性能可能会大幅下降。 重建整个表可以提高性能,因为数据和索引现在已经过优化。

如果您只是插入表中,MyISAM更适合这种情况。 如果仅追加,则不会出现锁定问题,因为记录已添加到文件末尾。 MyISAM还允许您使用MERGE表,这些表非常适合脱机或归档部分数据而无需进行导出和/或删除。

跟踪使用中的my.ini并增加key_buffer_size我有一个1.5GB的表,其中一个大键,其中每秒查询数(所有写入数)都降到了17.我发现在管理面板中很奇怪(在表中因为写入而被锁定以加快进程)它每秒执行200次InnoDB读取,每秒24次写入。

它被迫从磁盘上读取索引表。 我将key_buffer_size从8M更改为128M,性能跃升至每秒150次查询完成,只需执行61次读取即可获得240次写入。 (重启后)

更新表需要重建索引。 如果您正在进行批量插入,请尝试在一个事务中执行它们(如转储和还原那样)。 如果表是写偏的,我会考虑放弃索引或者让后台作业对表进行读处理(例如通过将其复制到索引表)。

可能是由于XFS碎片造成的?

复制/粘贴自http://stevesubuntutweaks.blogspot.com/2010/07/should-you-use-xfs-file-system.html

要检查驱动器的碎片级别,例如位于/ dev / sda6:

sudo xfs_db -c frag -r / dev / sda6

结果将如下所示:

实际51270,理想174,碎片因子99.66%

这是我第一次安装这些实用程序时得到的实际结果,以前不知道XFS维护。 非常讨厌。 基本上,分区上的174个文件分布在51270个单独的部分上。 要进行碎片整理,请运行以下命令:

sudo xfs_fsr -v / dev / sda6

让它运行一段时间。 -v选项让它显示进度。 完成后,尝试再次检查碎片级别:

sudo xfs_db -c frag -r / dev / sda6

实际176,理想174,碎片因子1.14%

好多了!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM