为什么在只有几个索引的情况下,大型表上的MySQL InnoDB插入/更新会变得非常慢?

为什么在只有几个索引的情况下,大型表上的MySQL InnoDB插入/更新会变得非常慢?,mysql,performance,indexing,Mysql,Performance,Indexing,我们有一系列表,它们已经有机地增长到数百万行,在生产中执行插入或更新可能需要两秒钟。但是,如果我转储表并从转储查询中重新创建它,速度会非常快 我们通过创建一个副本重建索引,然后进行重命名切换并复制任何新行,从而重建了其中一个表,这是有效的,因为该表只被追加到。这样做可以使插入和更新的速度极快 我的问题是: 为什么插入会随时间变慢? 为什么重新创建表并进行导入可以解决这个问题? 有没有什么方法可以在不锁定表进行更新的情况下重建索引?听起来好像是 指数随时间不平衡 磁盘碎片 内部innodb数据文

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

我们通过创建一个副本重建索引,然后进行重命名切换并复制任何新行,从而重建了其中一个表,这是有效的,因为该表只被追加到。这样做可以使插入和更新的速度极快

我的问题是:

为什么插入会随时间变慢? 为什么重新创建表并进行导入可以解决这个问题?
有没有什么方法可以在不锁定表进行更新的情况下重建索引?

听起来好像是

  • 指数随时间不平衡
  • 磁盘碎片
  • 内部innodb数据文件碎片
您可以尝试
analyze table foo
,它不需要锁,只需要几次索引,只需几秒钟

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

mysql> SET PROFILING=1;
mysql> INSERT INTO foo ($testdata);
mysql> show profile for QUERY 1;
你应该知道大部分时间都花在哪里了


显然,按PK顺序插入时innodb的性能更好,这是您的情况吗?

更新表需要重建索引。如果要进行大容量插入,请尝试在一个事务中进行(就像转储和还原一样)。如果表有写偏见,我会考虑无论如何删除索引,或者让后台作业对表进行读取处理(例如,将其复制到索引表)。

这可能是因为XFS的碎片吗

复制/粘贴自:

要检查驱动器的碎片级别,例如位于/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%

好多了


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


如果只在表中插入,MyISAM更适合这样做。如果只是追加,就不会有锁定问题,因为记录被添加到文件的末尾。MyISAM还允许您使用合并表,这非常适合脱机或归档部分数据,而无需进行导出和/或删除。

跟踪正在使用的my.ini并增加
键缓冲区大小
我有一个1.5GB的表,表中有一个大键,其中每秒的查询(所有写入)减少到17。我觉得奇怪的是,在管理面板中(为了加快进程,表被锁定写入),它每秒执行200次InnoDB读取到24次写入


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

存储引擎?文件系统?MySQL版本?记录很大吗?对不起,应该包括这个问题!InnoDB,XFS在一个拥有15k磁盘的raid阵列上。我想你没有读过这个问题,当索引重建后,插入/更新速度非常快,即使用optimize table时,只有当表的增长是有机的时,插入/更新速度才慢。我想知道这是为什么。出于某种原因,我有偏见,你做批量更新,即有时添加更多的行,有时添加更少的突发。我想它是快速的,只要你下降指数?我没有尝试下降指数,我不能在生产中这样做,一旦我导入一个测试机器上的转储,它是快速的。不过,我认为降低指数会让它变得更快。我可能需要尝试将数据文件复制到一台测试机器上进行测试。那么“插入延迟”是否有帮助呢?但是,可能不支持innodb…:-/是的,InnoDB不支持,我认为这也会带来很多问题。你有关于索引不平衡信息的链接吗?另外,我认为你可能发现了磁盘碎片的问题。。。我将对此进行调查。我记得我被这个问题击中了,这更像是“64位平台上的错误索引统计”,但这可能会导致类似的问题。对于innoDB,innodb_buffer_pool_大小直接影响存储在内存中的行/索引的数量,从而减少写入前的冲突查找。key_buffer_大小对innodb没有影响,它是myisam设置。引用“严重依赖RAM”。有关innodb的详细信息。注意InnoDB从5.0到5.1、5.5及更高版本有了很大的改进。