如何估计/预测 MySQL 中表的数据大小和索引大小

Abd*_*naf 37 mysql innodb

我正在寻找估算表格大小的最佳方法,因为我研究了很多博客和论坛,但找不到任何准确的答案

例如,我们有一个带有 InnoDB 引擎表 City,假设在未来(未来 1 年)它将有 100 万条记录,那么该表在此期间的估计数据大小和索引大小是多少。

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)
Run Code Online (Sandbox Code Playgroud)

更新

100 万条记录的估计上限(表的最大大小)是多少,我们如何估计它。

Rol*_*DBA 63

鉴于表描述,我看到

  • 每行数据 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;
Run Code Online (Sandbox Code Playgroud)

测量按数据库和存储引擎分组的所有表

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;
Run Code Online (Sandbox Code Playgroud)

运行这些查询,您可以跟踪数据库/引擎磁盘使用情况的变化。

试一试 !!!


小智 5

如果您使用 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';
Run Code Online (Sandbox Code Playgroud)

索引 PRIMARY 是数据本身。


小智 0

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';
Run Code Online (Sandbox Code Playgroud)

通过执行此查询,您可以获得表的大小DataIndex您可以根据行数检查此大小并预测 100 万行