Mysql InnoDB中是否有估算索引大小的公式?

Mysql InnoDB中是否有估算索引大小的公式?,mysql,innodb,rdbms,Mysql,Innodb,Rdbms,如何计算InnoDB中特定列类型的索引大小,即: 瓦尔查尔 煤焦 时间戳 斯莫林 我找到了MyISAM()的一个公式:(key_length+4)/0.67 这对InnoDB也适用吗 我试图估计我设计的数据库的大小,以确定大小。一个辅助索引记录是索引字段+主键。将字段大小相加,乘以记录数,再加上一些开销,这就是索引大小 一个辅助索引记录是索引字段+主键。将字段大小相加,乘以记录数,再加上一些开销,这就是索引大小 在InnoDB中,主键嵌入了数据,因此您可以认为它不占用空间 对于辅助密钥。。。

如何计算InnoDB中特定列类型的索引大小,即:

  • 瓦尔查尔
  • 煤焦
  • 时间戳
  • 斯莫林
我找到了MyISAM()的一个公式:(key_length+4)/0.67

这对InnoDB也适用吗


我试图估计我设计的数据库的大小,以确定大小。

一个辅助索引记录是索引字段+主键。将字段大小相加,乘以记录数,再加上一些开销,这就是索引大小

一个辅助索引记录是索引字段+主键。将字段大小相加,乘以记录数,再加上一些开销,这就是索引大小

在InnoDB中,
主键
嵌入了数据,因此您可以认为它不占用空间

对于辅助密钥。。。采用MyISAM公式,但同时包含辅助键和
主键的列。然后乘以3。(有很多开销。)尽管如此,答案在两个方向上都可能相差2倍

请注意,如果您有很多次键,那么主键的大小会对表+索引的总体空间产生很大的影响

示例

SET @db = 'world', @tbl = 'cities';
    SELECT      n_rows AS 'Approx Rows',
                'Data & PK' AS 'Type',
                clustered_index_size * 16384 AS Bytes,
                ROUND(clustered_index_size * 16384 / n_rows) AS 'Bytes/row',
                clustered_index_size AS Pages,
                ROUND(n_rows / clustered_index_size) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE database_name = @db
          AND table_name = @tbl
    UNION
        SELECT  n_rows,
                'Secondary Indexes' AS 'BTrees',
                sum_of_other_index_sizes * 16384 AS Bytes,
                ROUND(sum_of_other_index_sizes * 16384 / n_rows) AS 'Bytes/row',
                sum_of_other_index_sizes AS Pages,
                ROUND(n_rows / sum_of_other_index_sizes) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE database_name = @db
          AND table_name = @tbl
          AND sum_of_other_index_sizes > 0
          ;
-- (Percona has a different way.)
输出:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2637973 | Data & PK         | 179077120 |        68 | 10930 |       241 |
|     2637973 | Secondary Indexes | 232341504 |        88 | 14181 |       186 |
+-------------+-------------------+-----------+-----------+-------+-----------+
该表有两个索引:

PRIMARY KEY(...)  -- 14 bytes
INDEX(state, population)
INDEX(state, city)
  state CHAR(2) CHARACTER SET ascii -- 2 bytes
  population INT UNSIGNED -- 4 bytes
  city  -- AVG(LENGTH(city)) = 1+9.07 bytes

COUNT(*): 2,699,354  (the InnoDB estimate was not too far from this)

First index:  20    bytes * 2.7M rows = 54MB
Second index: 26.07 bytes * 2.7M rows = 70MB
Total:  124MB
Actual: 232MB
Ratio: 1.9x  (note: I skipped the "/0.67")
为了证明另一点,我尝试了
优化表
。之后的统计数据基本相同:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2685828 | Data & PK         | 179077120 |        67 | 10930 |       246 |
|     2685828 | Secondary Indexes | 232341504 |        87 | 14181 |       189 |
+-------------+-------------------+-----------+-----------+-------+-----------+

在InnoDB中,
主键
嵌入了数据,因此您可以认为它不占用空间

对于辅助密钥。。。采用MyISAM公式,但同时包含辅助键和
主键的列。然后乘以3。(有很多开销。)尽管如此,答案在两个方向上都可能相差2倍

请注意,如果您有很多次键,那么主键的大小会对表+索引的总体空间产生很大的影响

示例

SET @db = 'world', @tbl = 'cities';
    SELECT      n_rows AS 'Approx Rows',
                'Data & PK' AS 'Type',
                clustered_index_size * 16384 AS Bytes,
                ROUND(clustered_index_size * 16384 / n_rows) AS 'Bytes/row',
                clustered_index_size AS Pages,
                ROUND(n_rows / clustered_index_size) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE database_name = @db
          AND table_name = @tbl
    UNION
        SELECT  n_rows,
                'Secondary Indexes' AS 'BTrees',
                sum_of_other_index_sizes * 16384 AS Bytes,
                ROUND(sum_of_other_index_sizes * 16384 / n_rows) AS 'Bytes/row',
                sum_of_other_index_sizes AS Pages,
                ROUND(n_rows / sum_of_other_index_sizes) AS 'Rows/page'
        FROM mysql.innodb_table_stats
        WHERE database_name = @db
          AND table_name = @tbl
          AND sum_of_other_index_sizes > 0
          ;
-- (Percona has a different way.)
输出:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2637973 | Data & PK         | 179077120 |        68 | 10930 |       241 |
|     2637973 | Secondary Indexes | 232341504 |        88 | 14181 |       186 |
+-------------+-------------------+-----------+-----------+-------+-----------+
该表有两个索引:

PRIMARY KEY(...)  -- 14 bytes
INDEX(state, population)
INDEX(state, city)
  state CHAR(2) CHARACTER SET ascii -- 2 bytes
  population INT UNSIGNED -- 4 bytes
  city  -- AVG(LENGTH(city)) = 1+9.07 bytes

COUNT(*): 2,699,354  (the InnoDB estimate was not too far from this)

First index:  20    bytes * 2.7M rows = 54MB
Second index: 26.07 bytes * 2.7M rows = 70MB
Total:  124MB
Actual: 232MB
Ratio: 1.9x  (note: I skipped the "/0.67")
为了证明另一点,我尝试了
优化表
。之后的统计数据基本相同:

+-------------+-------------------+-----------+-----------+-------+-----------+
| Approx Rows | Type              | Bytes     | Bytes/row | Pages | Rows/page |
+-------------+-------------------+-----------+-----------+-------+-----------+
|     2685828 | Data & PK         | 179077120 |        67 | 10930 |       246 |
|     2685828 | Secondary Indexes | 232341504 |        87 | 14181 |       189 |
+-------------+-------------------+-----------+-----------+-------+-----------+

谢谢文件上有这个吗?我到处都找不到,不是真的。
*3
是通过检查几十个表而根据经验得出的。(这可能是更多或更少,取决于各种情况。)杰里米·科尔的一些博客探讨了数据存储方式的血淋淋的细节。如果你仔细阅读这些细节,你可能不会得到比我简单的
*3
更好的答案——许多因素会影响公式。在一个极端情况下,一个带有一个二级索引的单行表将为数据分配一个16KB的块,为索引分配另一个块。这远远超过了
*3
。索引可以是碎片化的,也可以是新碎片化的;这至少会造成
*1.5
的差异,可能会更大。
ROW\u格式可能有一些影响;我不知道有多少。我加的例子是1.9倍,如果是3倍。这种变化是意料之中的。
mysql.innodb_table_stats
直到mysql 5.6(2011年)和MariaDB 10.0才可用。在此之前,您只有
显示表格状态
。谢谢。文件上有这个吗?我到处都找不到,不是真的。
*3
是通过检查几十个表而根据经验得出的。(这可能是更多或更少,取决于各种情况。)杰里米·科尔的一些博客探讨了数据存储方式的血淋淋的细节。如果你仔细阅读这些细节,你可能不会得到比我简单的
*3
更好的答案——许多因素会影响公式。在一个极端情况下,一个带有一个二级索引的单行表将为数据分配一个16KB的块,为索引分配另一个块。这远远超过了
*3
。索引可以是碎片化的,也可以是新碎片化的;这至少会造成
*1.5
的差异,可能会更大。
ROW\u格式可能有一些影响;我不知道有多少。我加的例子是1.9倍,如果是3倍。这种变化是意料之中的。
mysql.innodb_table_stats
直到mysql 5.6(2011年)和MariaDB 10.0才可用。在此之前,您只需
显示表格状态