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

时间:2010-02-08 16:00:46

标签: mysql performance indexing

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

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

我的问题:

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

5 个答案:

答案 0 :(得分:9)

听起来好像是

  • 指数随时间的不平衡
  • 磁盘碎片
  • 内部innodb数据文件碎片

您可以尝试analyze table foo,它不需要锁定,只需要几次索引潜水并且需要几秒钟。

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

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

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

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

答案 1 :(得分:8)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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

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

答案 4 :(得分:0)

可能是由于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%

     

好多了!