适当使用mysql Optimize Table

Dan*_* A. 9 mysql innodb optimization maintenance

我想提出一些维护我们的 MySQL 数据库、版本 5.5/6 和使用 InnoDB 的最佳实践。

我遇到了这篇文章,它基本上是在说优化表:

  1. 如果您的查询不使用 PK,则不会有太大的改进。
  2. 表上的其他索引以伪随机顺序构建,很可能不会从优化表中受益。
  3. 实际上可能会使更新变慢,因为现在每个更改都有更高的概率导致页面拆分。

我的问题是:

  1. 以上 3 点总是正确的吗?部分?一点也不?
  2. 什么时候可以尝试优化表格?
  3. 在哪些情况下优化表不会受益,甚至会使表的某些用途变得更糟?
  4. 除了PK之外,有没有办法优化表的索引?

jyn*_*nus 7

该博文的作者 Baron Schwartz 是High Performance MySQL, 3rd Edition的合著者之一,这是关于 MySQL 性能的最好的书籍之一。虽然权威的论据并不总是好的,但我想说的是,他可能知道自己在说什么。

虽然他所说的一切都是正确的 - 以我的拙见 - 但你必须理解实际的基本论点:在许多情况下对 InnoDB 表进行碎片整理是无用的(为了性能),而且许多建议经常这样做的人是错误的。

碎片和分页是一个微妙的话题,像 Jeremy Cole 这样的人http://blog.jcole.us/2013/04/09/innodb-bugs-found-during-research-on-innodb-data-storage/和Facebook 工程师提到了很多(特别是关于压缩):https : //www.facebook.com/note.php?note_id=10150348315455933及其对性能的影响。

很多时候,您的性能取决于负载 - 您是否使用自动增量插入?您是否在表格中间多次插入和删除?如果您的表非常动态,您能负担得起额外的磁盘空间吗?

我可以向您推荐一些好的做法(这可能是您想要的):

  • 仅当您对大量记录进行了批量删除(并且您不打算将它们插回)时才进行碎片整理。在其他情况下,可能没有必要。如果您想知道逻辑数据和文件大小之间是否存在巨大差异,请将 .idb 文件与 show table status 中的数据 + 索引大小进行比较。
  • 通过始终按 PRIMARY KEY 顺序插入来加速插入,因此您不会强制进行不必要的页面拆分。
  • 使用分区来隔离可能改变表内部结构的更改。
  • 没有办法“优化二级索引”,但我永远不会觉得有必要这样做。更改缓冲区确保对索引的更改/重新平衡异步完成,而不会出现巨大的性能问题。BTREE 应该始终保持平衡,因此假设您的更改缓冲区未满并且清除线程立即删除旧行记录,您的性能应该没问题。我认为“优化二级索引”的一种方法是删除索引并重新创建它(假设您使用的是 InnoDB 插件或 MySQL 5.5+),但我认为绝对没有理由这样做。

当然,如果你真的想深入研究这个话题,创建一些表,对它们进行碎片整理,然后检查你是否真的有一些收获。一般来说,表空间处理和统计信息收集在 InnoDB 上是相对自动的。