2021-08-22 15:16:57
MySQL 添加主键可以节省磁盘空间,尤其在表未显式定义主键时,InnoDB 会隐式创建名为 GEN_CLUST_INDEX 的内部主键,其开销显著高于显式主键。以下是具体分析:
隐式主键的磁盘开销当表未定义主键时,InnoDB 会自动生成一个隐藏的 GEN_CLUST_INDEX(聚簇索引),该索引包含整行数据。例如,在测试中,未定义主键的表 test1 磁盘占用为 748M,而显式添加主键后减少至 588M。这是因为:
隐式主键的 CLUST_INDEX_SIZE 和 OTHER_INDEX_SIZE 均较大(如示例中均为 24699),导致索引结构冗余。
显式主键替代隐式主键后,仅保留必要的聚簇索引和二级索引,减少了隐藏索引的开销。
显式主键的优化效果通过 ALTER TABLE test1 ADD PRIMARY KEY(a) 显式定义主键后:
隐式 GEN_CLUST_INDEX 被移除,仅保留主键索引和二级索引(如列 b 的索引)。
索引结构更紧凑,例如主键索引的 CLUST_INDEX_SIZE 降至 23733,整体磁盘占用减少约 21%。
不可见主键(GIPK)的替代方案若无法修改表结构添加显式主键,可通过以下方式优化:
启用不可见主键:设置 sql_generate_invisible_primary_key=1 后,InnoDB 会自动生成一个不可见的自增主键(如 my_row_id),避免隐式主键的开销。
兼容性:不可见主键对应用程序透明,但可通过查询直接使用(如分块读取数据),兼顾性能与业务逻辑。
主键与复制性能的关系
在 MGR 和 PXC 架构中,无主键的表会导致复制速度下降,因隐式主键的生成逻辑可能引发不一致。
显式主键(或不可见主键)可确保复制的稳定性,同时减少磁盘 I/O 和内存占用。
总结:添加主键通过消除隐式 GEN_CLUST_INDEX 的冗余开销,直接减少磁盘空间占用。对于遗留系统,建议优先使用不可见主键(GIPK)平衡性能与兼容性。