MySQL:在固定列的表上需要OPTIMIZE TABLE吗?

时间:2010-08-02 21:04:35

标签: mysql optimization

我有一个每周脚本,它从我们的实时数据库移动数据并将其放入我们的存档数据库,然后删除它刚刚从实时数据库存档的数据。因为它是一个不错的大小删除(大约10%的表被修剪),我想我应该在此删除后运行OPTIMIZE TABLE。

但是,我是从mysql文档中读到的,我不知道如何解释它: http://dev.mysql.com/doc/refman/5.1/en/optimize-table.html

“如果删除了表的大部分,或者对具有可变长度行的表(具有VARCHAR,VARBINARY,BLOB或TEXT列的表)进行了许多更改,则应使用OPTIMIZE TABLE。行保存在链表中,后续INSERT操作重用旧行位置。您可以使用OPTIMIZE TABLE回收未使用的空间并对数据文件进行碎片整理。“

第一句对我来说是模棱两可的。这是否意味着你应该运行它: A)您已删除了具有可变长度行的表的大部分,或者您对具有可变长度行的表进行了许多更改 要么 B)您删除了ANY表的大部分内容,或者您​​对具有可变长度行的表进行了很多更改

这有意义吗?因此,如果我的表没有VAR列,我是否还需要运行它?

虽然我们正在研究这个主题 - 是否有任何指示器告诉我OPTIMIZE呼叫表已经成熟?

另外,我读到这个http://www.xaprb.com/blog/2010/02/07/how-often-should-you-use-optimize-table/,说只运行OPTIMIZE表对主键很有用。如果我的大部分选择来自其他指数,我是否只是在拥有代理键​​的表上浪费精力?

非常感谢!

2 个答案:

答案 0 :(得分:4)

在您的场景中,我不认为定期优化表格会产生明显的差异。

首先,文档的第二个解释(B)是正确的 - “如果您删除了任何表的大部分内容,或者如果您对具有可变长度行的表进行了很多更改。”

如果您的表没有VAR列,则每条记录(无论其包含哪些数据)都占用表中完全相同的空间量。如果从表中删除了一条记录,并且数据库选择重复使用存储前一条记录的确切区域,则可以不浪费任何空间或分割数据。

就OPTIMIZE是否仅提高使用主键索引的查询的性能而言,该答案几乎肯定会因使用的存储引擎而异,我恐怕无法回答

但是,谈到存储引擎,如果你最终使用OPTIMIZE,请注意它不喜欢在InnoDB表上运行,因此该命令映射到ALTER并重建表,这可能是一个更昂贵的操作。无论哪种方式,表在优化期间都会锁定,因此在运行时要非常小心。

答案 1 :(得分:0)

MyISAM和InnoDB之间存在很多差异,我将这个答案分成两部分:

<强>的MyISAM

  • FIXED对MyISAM有一些含义。
  • “已删除的行在链表中维护,后续INSERT操作重用旧行位置”适用于MyISAM,而不是InnoDB。因此,对于带有 lot 流失的 MyISAM 表,OPTIMIZE可能是有益的。
  • 在MyISAM中,VAR加上DELETE / UPDATE会导致碎片化。
  • 由于链表和VAR,可以在数据文件(.MYD)中对单个行进行分段。 (否则,MyISAM行在数据文件中是连续的。)

<强> InnoDB的

  • FIXED对InnoDB表没有意义。
  • 对于InnoDB中的VAR,有“块拆分”,而不是链表。
  • 在BTree中,块分裂稳定在并且平均69%已满。因此,使用InnoDB,几乎任何滥用都会让桌子不会过于膨胀。也就是说,DELETE / UPDATE(有或没有VAR)导致更有限的BTree'碎片'。
  • 在InnoDB中,清空块(每个16KB)被放在“空闲列表”中以供重用;他们没有回到操作系统。
  • InnoDB中的数据按PRIMARY KEY排序,因此在表格的一部分删除 为另一部分中的新行提供空间表的一部分。但是,当释放时,可以在其他地方使用。
  • 两个相邻的半空的区块将合并,从而释放一个区块。

<强>两个

  • 如果要删除“旧”数据(10%),那么PARTITIONing很多更好的方法。见my blog。它涉及DROP PARTITION,它是瞬时的,并为操作系统提供空间,加上REORGANIZE PARTITION可以即时。
  • OPTIMIZE TABLE几乎不值得做。