我有一个大的SQL表,大约30 GB,我已经删除了大约一半。所以information_schema
没有保留正确的信息(直到数据库优化)。
有没有办法获得实际尺寸?使用全表扫描?
答案 0 :(得分:1)
使用InnoDB,许多数字相当模糊。单行的大小实际上是不可用的。 SHOW TABLE STATUS
(以及information_schema
的等效探测)为您提供估算值。但是这个估计可能会大大减少 - 有时超过2倍,高或低。
以下是InnoDB表格布局的简要概述。
数据存储在16KB块的BTree中,由PRIMARY KEY
排序。 (我不会讨论其他BTree中的二级索引。)
在这样的结构中插入行可能会在所需的块中找到空间,或者可能需要块拆分。删除行可能会标记块的一部分,并且可以(很少)将块返回到“自由空间”。
“avg_row_length”计算为磁盘空间减去“空闲”块,然后除以行数。
但这又到了另一个模糊数字。通过在BTree中进行一些探测来估计行数,以查看每个块有多少行,然后进行一些计算。
然后行长度是模糊磁盘空间(不考虑每个块中的空白空间)除以模糊行数。
我已提到“Data_free”。但请注意,插入/删除行时,如果不更改块数,则不会更改Data_free。
TEXT
列(包含一些警告,资格和例外)存储在单独的块中。分配单元有16KB块。因此,如果您有任何TEXT
或BLOB
列,则计算会非常混乱。
但我没有通过......微小的表被分配了几个16KB块,但是当它们变得“小”时,空间一次分配8MB。同样,其中一些可以在Data_free中看到;很不可能。
“免费”空间分为3类:
UPDATEs
和INSERTs
出现。对不起,你的数字不精确。
更改主题...为什么要进行大删除?如果你有一个滑动时间尺度(想想:新闻),PARTITIONs
非常好。如果要替换所有数据,则会想到RENAME TABLE
技巧。