如何查询实际的Mysql数据库大小?

3

我有一个大型的 SQL 表格,大约有30GB,我已经删除了其中一半。所以在数据库优化之前,information_schema 中保存的信息并不准确。 有没有一种方法可以使用完整表格扫描来获取实际大小?


你在寻找什么?磁盘利用率?行数?“空闲”空间?你查看了SHOW TABLE STATUS吗?innodb_file_per_table的值是多少? - Rick James
寻找每行确切大小的总和。换句话说,运行优化后表格的大小。 - Dima
这基本上是不可能预测的。也许最好的预测方法是观察您得到的值并进行插值/外推。 - Rick James
是的,现在我知道了...谢谢!也许我只需创建一个副本并在那里运行优化以保持生产运行。 - Dima
顺便说一下,我无法推断,因为我保存了JSON块,有一次它非常庞大,所以新数据要小得多。 - Dima
1个回答

1
使用InnoDB,许多数字相当模糊。单个行的大小实际上不可用。 SHOW TABLE STATUS(以及对information_schema的等效探针)给出一个估计值。但是这个估计值可能会显著偏离-有时高达2倍,高或低。以下是InnoDB表布局的简要概述。数据存储在16KB块的BTree中,按PRIMARY KEY排序。(我不会讨论其他BTrees中的辅助索引。)将行插入这样的结构可能会在所需块中找到空间,也可能需要进行块拆分。删除一行可能会标记部分块为空闲,并且可以(很少)将块返回到“空闲空间”。 “avg_row_length”是计算为磁盘空间减去“free”块,然后除以行数。但是,这涉及另一个模糊的数字。通过对BTree进行几次探测来估计行数,然后进行一些计算。
然后行长度是模糊磁盘空间(不考虑每个块中的空白空间)除以模糊行数。
我提到了“Data_free”。但请注意,插入/删除行时,如果它不更改块的数量,则不会更改Data_free。 TEXT列(在某些警告、限制和异常情况下)存储在单独的块中。分配单位为16KB块。因此,如果您有任何TEXTBLOB列,则计算变得非常混乱。
但我还没有结束……小表被分配了几个16KB块,但当它们变得更“小”时,空间每次分配8MB。同样,其中一些可以在Data_free中看到;其他很难。
“空闲”空间分为3类:
  • 在“Data_free”中可见,但未释放给操作系统。
  • UPDATEsINSERTs发生时的可重用块空间。
  • 不可见的开销。预计表的空间是每行每列长度总和的2-3倍。

抱歉,您只能使用不精确的数字。

改变话题... 你为什么要进行大量删除?如果您有一个滑动时间尺度(想象:新闻),则PARTITIONs非常好用。如果您正在替换所有数据,则可以考虑使用RENAME TABLE技巧。


基于日期吗?还是其他什么?如果基于日期,请考虑此链接。 - Rick James

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接