【发布时间】:2018-05-28 06:47:53
【问题描述】:
我有一个 MySQL 表,在 Google Cloud SQL 上托管了超过 30 亿行。
我想了解如何从列数据类型、行数和索引来解释磁盘上的总大小。
我希望它会是这样的
size_of_table_in_bytes = num_rows * [ Sum over i {bytes_for_datatype_of_column(i))}
+ Sum over j {Bytes_for_index(j)} ]
但我最终得到的磁盘大小不正确,而不是我的数据库大小显示的大小。
在上使用每个数据类型的字节数
https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
以及来自
的 InnoDB 标头和索引中的其他字节这里是我对header、每列和每一个索引占用的字节数的理解
TABLE `depth` (
Bytes| Column/Header/Index
2| variable length header Ceil(num columns/8) = Ceil (10/8)
5| Fixed Length Header
3|`date` date DEFAULT NULL,
7|`receive_time` datetime(3) DEFAULT NULL,
8|`instrument_token` bigint(20) unsigned DEFAULT NULL,
1|`level `tinyint(3) unsigned DEFAULT NULL,
2|`bid_count` smallint(5) unsigned DEFAULT NULL,
8|`bid_size` bigint(20) unsigned DEFAULT NULL,
4|`bid_price` float DEFAULT NULL,
4|`ask_price` float DEFAULT NULL,
8|`ask_size` bigint(20) unsigned DEFAULT NULL,
2|`ask_count` smallint(5) unsigned DEFAULT NULL,
6|KEY `date_time_sym (`date`,`receive_time`,`instrument_token`),
6|KEY `date_sym_time (`date`,`instrument_token`,`receive_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8`
总计 72 个字节。
但根据 SHOW TABLE STATUS,Avg_row_length = 79。
问题 1:我在哪里弄错了每行的字节数?
我有理由确定我的数据中没有空值。
假设,我在计算字节数时犯了一些错误,每行使用 79 个字节
并使用SELECT COUNT(*) 作为3,017,513,240 计算行数:
size_of_table_in_bytes = 79*3,017,513,240 = 238,383,545,960
另一种获取大小的方法是使用 MySQL 查询
SHOW TABLE STATUS from mktdata where Name = "depth";
这里我得到一个包含一行的表格输出,其中几个重要字段的值如下:
Name: depth
Engine:InnoDB
Version:10
Row_format:Dynamic
Rows: 1,72,08,21,447
Avg_row_length: 78
Index_length: 1,83,90,03,07,456
Data_length: 1,35,24,53,32,480
起初我很震惊,Rows 是 17 亿而不是 30.1 亿,但我在documentation 中发现了这个
- 行
行数。一些存储引擎,例如 MyISAM,存储确切的 数数。对于其他存储引擎,例如 InnoDB,这个值是一个近似值,可能与实际值相差 40% 到 50%。在这种情况下,请使用 SELECT COUNT(*) 获得准确的计数。
因此,30.1 亿似乎适合行数,因此我预计表大小为 238 GB。
但是,如果我把 Data_length 和 Index_length 加起来,我得到 319,145,639,936
问题 2:为什么我用一种方法得到 319 GB 而另一种方法得到 238 GB。如果有的话,哪一个是正确的?
此外,Google Cloud SQL 控制台显示的 SQL 数据库的总大小为 742 GB。我唯一拥有的另一张表trade 的行数正好是depth 的1/5 和5 列。将Data_length 和Index_length 相加的大小为57 GB。如果我添加两个表大小,我会得到 376 GB。
问题 3:742 GB 似乎大约是 376 GB(实际上是 752)的两倍。这可能是因为备份?我知道 Google Cloud SQL 每天会自动备份一次?
由于上述问题3的合理性,我怀疑我的size = num_rows*num_bytes_per_row的简单方法是错误的!这真的让我很困扰,并会感谢任何帮助解决这个问题。
【问题讨论】:
-
您使用的是
MySQL而不是MS SQL Server,请删除SQL-Server标签 -
您是否启用了二进制日志?如果是,您还必须考虑它们的大小。
-
谢谢,我刚刚检查了 log_bin = ON。如何检查它的大小?
-
SHOW BINARY LOGS; -
我得到一个以 Log_name,File_size 作为列的表。 872 行的 File_size 总和为 85,661,147,002。这解释了 85 GB 的磁盘空间?
标签: mysql database google-cloud-platform google-cloud-sql