mysql> desc City;
+-------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| CountryCode | char(3) | NO | MUL | | |
| District | char(20) | NO | | | |
| Population | int(11) | NO | | 0 | |
+-------------+----------+------+-----+---------+----------------+
5 rows in set (0.03 sec)
UPDATE
具有1百万条记录的估计上限(表的最大大小)是多少,我们如何估计它。
#1 楼
给定表描述,我看到每行数据66个字节
主键每行4个字节
国家代码索引每行7个字节
国家/地区的3个字节
国家/地区代码所附的集群密钥的4个字节
77个字节的数据和密钥的总数
这不考虑BTREE或表空间碎片的内务管理
对于一百万行,这将是77,000,000字节(73.43 MB)
对于表的测量,对于给定的表mydb .mytable,您可以运行此查询
SELECT
CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',SUBSTR(units,pw1*2+1,2)) DATSIZE,
CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',SUBSTR(units,pw2*2+1,2)) NDXSIZE,
CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',SUBSTR(units,pw3*2+1,2)) TBLSIZE
FROM
(
SELECT DAT,NDX,TBL,IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
FROM
(
SELECT data_length DAT,index_length NDX,data_length+index_length TBL,
FLOOR(LOG(IF(data_length=0,1,data_length))/LOG(1024)) px,
FLOOR(LOG(IF(index_length=0,1,index_length))/LOG(1024)) py,
FLOOR(LOG(data_length+index_length)/LOG(1024)) pz
FROM information_schema.tables
WHERE table_schema='mydb'
AND table_name='mytable'
) AA
) A,(SELECT 'B KBMBGBTB' units) B;
以测量按数据库和存储引擎分组的所有表
SELECT
IF(ISNULL(DB)+ISNULL(ENGINE)=2,'Database Total',
CONCAT(DB,' ',IFNULL(ENGINE,'Total'))) "Reported Statistic",
LPAD(CONCAT(FORMAT(DAT/POWER(1024,pw1),2),' ',
SUBSTR(units,pw1*2+1,2)),17,' ') "Data Size",
LPAD(CONCAT(FORMAT(NDX/POWER(1024,pw2),2),' ',
SUBSTR(units,pw2*2+1,2)),17,' ') "Index Size",
LPAD(CONCAT(FORMAT(TBL/POWER(1024,pw3),2),' ',
SUBSTR(units,pw3*2+1,2)),17,' ') "Total Size"
FROM
(
SELECT DB,ENGINE,DAT,NDX,TBL,
IF(px>4,4,px) pw1,IF(py>4,4,py) pw2,IF(pz>4,4,pz) pw3
FROM
(SELECT *,
FLOOR(LOG(IF(DAT=0,1,DAT))/LOG(1024)) px,
FLOOR(LOG(IF(NDX=0,1,NDX))/LOG(1024)) py,
FLOOR(LOG(IF(TBL=0,1,TBL))/LOG(1024)) pz
FROM
(SELECT
DB,ENGINE,
SUM(data_length) DAT,
SUM(index_length) NDX,
SUM(data_length+index_length) TBL
FROM
(
SELECT table_schema DB,ENGINE,data_length,index_length FROM
information_schema.tables WHERE table_schema NOT IN
('information_schema','performance_schema','mysql')
AND ENGINE IS NOT NULL
) AAA GROUP BY DB,ENGINE WITH ROLLUP
) AAA) AA) A,(SELECT ' BKBMBGBTB' units) B;
运行这些查询,就可以跟踪数据库/引擎磁盘使用情况的变化。
试试看!
评论
对于查看所有表大小,这是一个非常好的查询。
– ghayes
14年4月15日在22:01
如果您有CHARSET utf8,则CHAR长度需要乘以3。可以通过将计算增加一倍或三倍来估算整个开销。
–里克·詹姆斯(Rick James)
15年8月18日在23:27
@RolandoMySQLDBA,您是否知道是否可以计算表的“实际”行大小,并与实际大小(压缩表)进行比较并获得压缩率?
–ceinmart
19年6月19日在20:26
@ceinmart innodb_page_size是固定的(默认为16K或16384),并成为行和分组或拆分的边界。更改innodb_page_size可以更改数据存储的好坏,这取决于行的填充或稀疏程度(尤其是存在TEXT / BLOB / VARCHAR的情况)。充其量,您应该将.ibd文件的大小与模式报告的大小进行比较,以估计比率。您可能还需要执行NULL ALTER TABLE(ALTER TABLE ... ENGINE = InnoDB;),以获得准确的比率。努力可能不值得。
– RolandoMySQLDBA
19年6月19日在21:13
@ceinmart请记住,更改innodb_page_size并不是逐表设置。您需要完全导出数据(请参阅mariadb.com/kb/en/library/how-to-change-innodb_page_size)
– RolandoMySQLDBA
19年6月19日在21:15
#2 楼
如果您使用的是InnoDB表,则可以从mysql.innodb_index_stats
获取数据/个人索引的大小。 “大小”统计信息包含以页为单位的答案,因此您必须将其乘以页面大小,默认情况下为16K。 select database_name, table_name, index_name, stat_value*@@innodb_page_size
from mysql.innodb_index_stats where stat_name='size';
索引PRIMARY是数据本身。
评论
假设您在表中有数据;好像OP想要在填充之前进行估算。
–里克·詹姆斯(Rick James)
19年11月12日在6:25
#3 楼
如果您还没有数据,请参考以下提示。以下内容适用于InnoDB。 (MyISAM更简单,更小。)不要对可变长度列使用
CHAR
。您正在使用什么CHARACTER SET
? Ascii每个字符需要一个字节; utf8mb4需要1到4之间。间接费用。 1M行表最有可能在160MB和240MB之间。要测量单个索引,例如3个字节的
CountryCode
:4 bytes per INT
35 for CHAR(35), if ascii or latin1; varchar is probably less
3 for the country code; it is fixed length
etc
注意:
仅需要计算(BTree的)叶子节点;非叶子节点的开销通常为1%。
PRIMARY KEY
与数据“聚集”,因此无需计算。如果没有显式PK,则您需要在行大小上添加6个字节,以允许虚构PK。
ROW_FORMAT = COMPRESSED
缩小了2:1。 (这不像典型的zip(等)压缩率3:1那样好。)SHOW TABLE STATUS LIKE "tablename";
是计算“实际”大小的快速方法。有关数据和PK,请参见Data_length
。 Index_length
用于辅助索引,Data_free
用于其他内容。Index_length
很少超过Data_length
。但是,发生这种情况并非“错误”。#4 楼
SELECT Table_NAME "tablename",
data_length "table data_length in Bytes",
index_length "table index_length in Bytes",
data_free "Free Space in Bytes"
FROM information_schema.TABLES where Table_schema = 'databasename';
通过执行此查询,您可以获取用于表的
Data
和Index
的大小,您可以对照行数检查此大小并预测100万行评论
我不确定,但这会给出一些准确的结果吗?你有没有测试过?
–阿卜杜勒·玛纳夫(Abdul Manaf)
13年7月10日在12:18
实际上,我正在定期测试此查询结果,以查看w.r.t.的增长(%)。尺寸
– Peter Venderberghe
13年10月10日在12:40
#5 楼
这很乏味。但是细节在文档中。为了尽可能准确(这几乎是不必要的),您还需要阅读表结构和索引结构。
如果我穿上鞋子,我会建立表格,并在表格中填充一百万行测试数据,然后测量尺寸变化。根据您的应用程序,您可能还需要考虑事务日志文件的大小。
评论
这很棒。但是有可能明智地获得索引大小列。意思是如果您有一个表(例如)索引了5列。我们可以获取每个索引的大小吗?我会问另一个问题。谢谢