为什么InnoDB表的大小远大于预期?

ale*_*cci 8 mysql innodb

我正在试图找出不同存储引擎的存储要求.我有这张桌子:

CREATE TABLE  `mytest` (
  `num1` int(10) unsigned NOT NULL,
  KEY `key1` (`num1`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Run Code Online (Sandbox Code Playgroud)

当我插入一些值然后运行时,show table status;我得到以下内容:

+----------------+--------+---------+------------+---------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| Name           | Engine | Version | Row_format | Rows    | Avg_row_length | Data_length | Max_data_length  | Index_length | Data_free | Auto_increment | Create_time         | Update_time         | Check_time | Collation         | Checksum | Create_options | Comment |
+----------------+--------+---------+------------+---------+----------------+-------------+------------------+--------------+-----------+----------------+---------------------+---------------------+------------+-------------------+----------+----------------+---------+
| mytest         | InnoDB |      10 | Compact    | 1932473 |             35 |    67715072 |                0 |     48840704 |   4194304 |           NULL | 2010-05-26 11:30:40 | NULL                | NULL       | latin1_swedish_ci |     NULL |                |         |

注意avg_row_length是35.我感到困惑的是,当我只存储一个不可为空的整数时,InnoDB不会更好地利用空间.

我在myISAM上运行了同样的测试,默认情况下myISAM在这个表上每行使用7个字节.我跑的时候

ALTER TABLE mytest MAX_ROWS=50000000, AVG_ROW_LENGTH = 4;
Run Code Online (Sandbox Code Playgroud)

导致myISAM最终正确使用5字节行.

当我为InnoDB运行相同的ALTER TABLE语句时,avg_row_length不会改变.

为什么只存储一个4字节的无符号整数时需要这么大的avg_row_length?

Qua*_*noi 10

InnoDB表是集群的,这意味着所有数据都包含在a中B-Tree,PRIMARY KEY作为键,所有其他列作为有效负载.

由于未定义显式PRIMARY KEY,因此InnoDB使用隐藏的6字节列对记录进行排序.

B-Tree组织的这个和开销(具有额外的非叶级块)需要更多的空间sizeof(int) * num_rows.