解释mysql的information_schema.tables DATA_LENGTH,INDEX_DATA_LENGTH和DATA_FREE

esi*_*ver 6 mysql

我希望有人可以解释为什么两小时的数据清除据称导致我的mysql实例上的数据使用量减少了32 KB.这是我的详细信息:

我有一个mysql数据库(在Amazon RDS上运行),我试图清除数据.我这样做是为了避免耗尽存储空间,因为亚马逊会限制你1TB,如果我们不采取任何行动,我们最终会达到这个限制.

我正在使用此命令来计算我的表和索引的大小:

select * from information_schema.tables;
Run Code Online (Sandbox Code Playgroud)

特别是有两个InnoDB表占用了我的大部分存储空间.我有一个进程迭代我最大的表删除记录.在时间t = 0,我运行上面的SQL查询,并得到以下数据长度和索引数据长度的结果:

  • 数据长度:56431116288
  • 索引数据长度:74233151488

两个小时后,在连续运行数据库清理程序之后,我运行了上面的SQL语句并获得了以下内容:

  • 数据长度:56431083520
  • 索引数据长度:74126147584

这基本上意味着我削减了32 KB的表数据和102 MB的索引数据.

指数的减少是有道理的.表格数据的减少非常小.在此期间不可能插入其他数据,因为我在我的数据库的备份副本上运行此测试(关于RDS的一个好处是,您可以完全复制数据库并运行以运行实验在,例如这一个).我还确认AUTO_INCREMENT值两次都相同.

有人可以解释为什么数据长度没有太大变化吗?数据长度只是一个非常快速和肮脏的近似值吗?mysql最终会有其他一些压缩步骤吗?或者我是否完全误解了这些领域的使用?

谢谢!

更新

我可能已经弄明白了 - 在时间t = 0

  • DATA_FREE = 77594624

四小时后,

  • DATA_FREE = 256901120

这意味着我已经将DATA_FREE增加了大约171MB.

这是否意味着如果我插入另一个171MB,它将来自DATA_FREE池,所以我的数据长度不会增加?

换句话说,假设我从一个新的InnoDB表开始并插入20 GB的数据(假设20 GB包含所有多余的InnoDB内容,我意识到InnoDB中存储的数据大于MyISAM),然后我删除所有数据,然后我插入10 GB的数据.当我从information_schema.tables运行select*时,我应该看到10 GB的数据长度和10 GB的数据,对吧?我不应该期望看到数据长度为30 GB /数据的0 GB,也不应该期望看到数据长度为10 GB/10 GB的数据?

更新2

Stack Overflow上的这篇文章似乎也证实了我的分析.

小智 4

表的“数据长度”包括表内可能存在的任何可用空间。您可能需要对OPTIMIZE表进行碎片整理,以释放该空间。请注意,这可能会在执行操作时将表锁定一段时间。

使用 InnoDB 存储引擎(InnoDB CREATE TABLE ( ... ) ENGINE=InnoDB;)将使表优化在很大程度上变得不必要,并且使数据库通常更快。如果您还没有使用它,那么您可能应该开始使用它。:)

  • 数据长度可能不包括可用磁盘空间。在我最近进行主要维护的表上,我有以下值:1.35GB 数据长度、1.3GB 索引长度、6.1GB 可用数据。另外,这是一个 InnoDB 表。使用 InnoDB 并不“使得表优化在很大程度上变得不必要” (2认同)