【问题标题】:MySQL: OPTIMIZE TABLE needed on table with fixed columns?MySQL:具有固定列的表需要 OPTIMIZE TABLE?
【发布时间】:2016-02-03 09:24:42
【问题描述】:

我有一个每周脚本,它从我们的实时数据库中移动数据并将其放入我们的存档数据库,然后删除它刚刚从实时数据库中存档的数据。由于这是一个相当大的删除(大约 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 表只对主键有用。如果我的大部分选择来自其他索引,我是否只是在具有代理键的表上浪费精力?

非常感谢!

【问题讨论】:

    标签: mysql optimization


    【解决方案1】:

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

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

    如果您的表没有 VAR 列,则每条记录(无论它包含什么数据)都会占用表中完全相同的空间量。如果从表中删除了一条记录,并且数据库选择重用存储先前记录的确切区域,它可以这样做而不会浪费任何空间或使您的数据碎片化。

    至于 OPTIMIZE 是否只提高使用主键索引的查询的性能,这个答案几乎肯定会根据所使用的存储引擎而有所不同,恐怕我无法回答这个问题.

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

    【讨论】:

    • 谢谢,瑞恩。我正在使用 InnoDB 并且肯定注意到了锁,这就是为什么我要确保我没有过度使用它。因此,如果我理解正确,因为我的表不使用任何 VAR 列,它不会像碎片一样。好的,很高兴知道,谢谢!
    【解决方案2】:

    MyISAM 和 InnoDB 之间有很多不同之处,我将这个答案一分为二:

    MyISAM

    • FIXED 对 MyISAM 有一些意义。
    • “删除的行在链表中维护,后续的 INSERT 操作重用旧的行位置”适用于 MyISAM,不适用于 InnoDB。因此,对于具有 大量 流失率的 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 几乎不值得去做。

    【讨论】:

    • “OPTIMIZE TABLE 几乎不值得做”为什么?
    • @lonix - 索引(和数据)存储在 BTree 中。 (阅读此类。)访问行的速度不取决于表中的块数,而是树的深度。优化减少了块的数量(一些),但很少改变深度。维护良好的 BTree 甚至不会像优化表之后的两倍大。 (完整的答案需要更多讨论。)
    • 谢谢,这是有道理的。所以这不是您需要为您的 wordpress 网站考虑的事情 - 除非您在企业环境中运行庞大的数据库,否则 OPTIMIZE 在任何情况下都不会产生太大影响,因为它基本上 过早优化我>?
    • @lonix - 还记得软盘时代吗?那时,每个人都在不断地寻找一种“碎片整理”的方法,并以其他方式缩小事物所需的磁盘空间。我怀疑OPTIMIZE 是因为这样的概念而发明的。广告磁盘变得又大又快,压缩、碎片整理和OPTIMIZEing 已基本无用。
    猜你喜欢
    • 2010-11-05
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多