开发者

MySQL压缩表创建方法示例详解

目录
  • 一句话总结
  • 一、支持压缩的表空间类型回顾
  • ️ 二、方法一:在“独立表空间”中创建压缩表
    • ✅ 前提条件:
    • ✅ 创建语句:
    • 参数说明:
  • 三、方法二:在“通用表空间”中创建压缩表
    • ✅ 步骤 1:先创建通用表空间,指定FILE_block_SIZE
    • ✅ 步骤 2:创建表时,KEY_BLOCK_SIZE必须匹配
    • 关键规则:
  • 四、重要注意事项(Notes)
    • 1️⃣ mysql 8.0 起:压缩表空间文件更小
    • 2️⃣ROW_FORMAT=COMPRESSED和KEY_BLOCK_SIZE可以互相推导
    • 3️⃣ 如何选择最佳KEY_BLOCK_SIZE?
    • 4️⃣KEY_BLOCK_SIZE是“提示”,不是强制
    • 5️⃣ 大页(32KB/64KB)不支持压缩!
    • 6️⃣ 设置KEY_BLOCK_SIZE = 16有意义吗?
    • 7️⃣ 所有索引都会被压缩
  • 五、压缩表的限制(Restrictions)
    • 六、参数对比表(关键区别)
      • ✅ 七、完整示例:推荐做法
        • 场景:在通用表空间中创建压缩表
      • ✅ 总结:关键要点

        这段内容是 MySQL 官方文档 17.9.1.2 节:创建压缩表(Creating Compressed Tables),它详细说明了如何在两种不同类型的表空间中创建 InnoDB 压缩表,并解释了相关的语法、限制和注意事项。

        我们来一步步拆解、翻译并通俗化讲解,让你彻底理解:

        ✅ 如何正确创建一个压缩表

        ⚠️ 需要注意哪些坑

        各参数的含义与关系

        一句话总结

        你可以通过 ROW_FORMAT=COMPRESSEDKEY_BLOCK_SIZE独立表空间(file-per-table)通用表空间(general tablespace) 中创建压缩表,但 不能在系统表空间中使用压缩。两者配置方式略有不同,尤其是通用表空间需要预先定义 FILE_BLOCK_SIZE

        一、支持压缩的表空间类型回顾

        表空间类型是否支持压缩说明
        ✅ 文件独立表空间(.ibd 文件)每个表一个文件,默认开启
        ✅ 通用表空间(General Tablespace)多个表共享一个 .ibd 文件
        ❌ 系统表空间(ibdata1包含系统数据(如 undo log),不支持压缩

        所以:只要你的表不是放在 ibdata1 里,就可以压缩。

        ️ 二、方法一:在“独立表空间”中创建压缩表

        ✅ 前提条件:

        • innodb_file_per_table=ON(默认就是 ON)
        SET GLOBAL innodb_file_per_table = 1; -- 可选:确保启用(通常已默认)

        ✅ 创建语句:

        CREATE TABLE t1 (
          c1 INT PRIMARY KEY
        ) 
        ROW_FORMAT = COMPRESSED 
        KEY_BLOCK_SIZE = 8;
        

        参数说明:

        参数作用
        ROW_FORMAT=COMPRESSED明确启用压缩
        KEY_BLOCK_SIZE=8目标压缩页大小为 8KB(单位是 KB)

        实际磁盘上的页会被压缩到接近这个大小(如原始 16KB → 压缩成 ~8KB)

        三、方法二:在“通用表空间”中创建压缩表

        这是重点,比独立表空间复杂一些。

        ✅ 步骤 1:先创建通用表空间,指定FILE_BLOCK_SIZE

        CREATE TABLESPACE `ts2` 
        ADD DATAFILE 'ts2.ibd' 
        FILE_BLOCK_SIZE = 8192 
        ENGINE=InnoDB;
        
        • FILE_BLOCK_SIZE = 8192:表示这个表空间的 物理块大小是 8KB
        • 单位是 字节(注意!和 KEY_BLOCK_SIZE 不同)

        ✅ 步骤 2:创建表时,KEY_BLOCK_SIZE必须匹配

        CREATE TABLE t4 (
          c1 INT PRIMARY KEY
        ) 
        TABLESPACE ts2 
        ROW_FORMAT = COMPRESSED 
        KEY_BLOCK_SIZE = 8;  -- 8192 字节 = 8KB
        

        关键规则:

        KEY_BLOCK_SIZE(单位 KB)必须等于 FILE_BLOCK_SIZE / 1024

        innodb_page_sizeFILE_BLOCK_SIZEKEY_BLOCK_SIZE
        16384 (16KB)8192 (8KB)8
        1638440964
        1638420482

        ❌ 如果不匹配?→ 报错!

        四、重要注意事项(Notes)

        1️⃣ MySQL 8.0 起:压缩表空间文件更小

        “The tablespace file for a compressed table is 编程客栈created using the physical page size…”

        • 以前:空压缩表也占满 16KB 一页
        • 现在:直接按压编程缩后的大小分配空间 → 初始 .ibd 文件更小

        ✅ 好处:节省空间,启动更快

        2️⃣ROW_FORMAT=COMPRESSED和KEY_BLOCK_SIZE可以互相推导

        你写的实际效果
        ROW_FORMAT=COMPRESSED(无 KEY_BLOCK_SIZE自动设为 innodb_page_size / 2 → 通常是 8KB
        KEY_BLOCK_SIZE=4(无 ROW_FORMAT自动启用压缩

        所以这两个参数写一个就行,另一个可省略。

        3️⃣ 如何选择最佳KEY_BLOCK_SIZE?

        文档建议:

        &ldquo编程客栈;typically you create several copies of the same table with different values… then measure performance”

        ✅ 推荐做法:

        1. 创建多个副本:KEY_BLOCK_SIZE=8, 4, 2
        2. 导入真实数据
        3. 测量:
          • .ibd 文件大小
          • 查询性能(TPS/QPS)
          • CPU 使用率
        4. 选择综合最优值

        经验值:

        • 大多数场景用 8 就很好
        • 数据特别大或 SSD 成本敏感 → 尝试 42

        4️⃣KEY_BLOCK_SIZE是“提示”,不是强制

        • InnoDB 可能根据实际情况调整
        • 如果设得太大(> innodb_page_size)→ 忽略,警告,自动改为一半
        • 如果 innodb_strict_mode=ON(默认)→ 直接报错

        5️⃣ 大页(32KB/64KB)不支持压缩!

        “InnoDB supports 32KB and 64KB page sizes but these do not support compression.”

        • innodb_page_size=3276865536 → 无法使用压缩
        • 所以想用压缩,必须保持 innodb_page_size ≤ 16KB

        6️⃣ 设置KEY_BLOCK_SIZE = 16有意义吗?

        • 对于独立表空间:

          • KEY_BLOCK_SIZE=16 → 通常压缩率很低(因为原始页就是 16KB)
          • 但对 包含大量 BLOB/TEXT 的表 仍可能js有效,因为这些字段会存到“溢出页”(ofjsf-page),压缩后可减少溢出页数量
        • 对于通用表空间:

          • 不允许 KEY_BLOCK_SIZE = innodb_page_size
          • 必须小于原始页大小

        7️⃣ 所有索引都会被压缩

        “All indexes of a table… are compressed using the same page size”

        • 主键(聚簇索引)、二级索引、唯一索引 → 全部压缩
        • 压缩是 整表级别 的,不是按行或按索引设置
        • CREATE INDEX 时不支持指定压缩参数(会被忽略)

        五、压缩表的限制(Restrictions)

        限制说明
        ❌ 不能在系统表空间中压缩ibdata1 不支持
        ❌ 通用表空间内不能混用压缩和非压缩表要么全压缩,要么全不压缩
        ❌ 不支持压缩临时表CREATE TEMPORARY TABLE ... COMPRESSED → 报错或自动转为非压缩
        ❌ 压缩是整表行为不能只压缩某几列或某几个索引
        CREATE INDEX 不支持压缩语法但继承表的压缩设置

        六、参数对比表(关键区别)

        参数出现场景单位示例说明
        innodb_page_size全局配置字节16384内存中的原始页大小(默认 16KB)
        KEY_BLOCK_SIZECREATE TABLEKB8目标压缩页大小(KB)
        FILE_BLOCK_SIZECREATE TABLESPACE字节8192通用表空间的物理块大小

        记住:KEY_BLOCK_SIZE = FILE_BLOCK_SIZE / 1024

        ✅ 七、完整示例:推荐做法

        场景:在通用表空间中创建压缩表

        -- 1. 创建通用表空间(8KB 物理块)
        CREATE TABLESPACE `compressed_ts` 
        ADD DATAFILE 'compressed_ts.ibd' 
        FILE_BLOCK_SIZE = 8192 
        ENGINE=InnoDB;
        -- 2. 创建压缩表(KEY_BLOCK_SIZE=8)
        CREATE TABLE sales_archive (
          id BIGINT AUTO_INCREMENT PRIMARY KEY,
          product VARCHAR(100),
          amount DECIMAL(10,2),
          created_date DATE
        ) TABLESPACE compressed_ts 
          KEY_BLOCK_SIZE = 8;  -- ROW_FORMAT=COMPRESSED 自动启用

        ✅ 总结:关键要点

        要点说明
        ✅ 支持压缩的表空间file-per-tablegeneral tablespace
        ❌ 不支持系统表空间、临时表
        启用方式ROW_FORMAT=COMPRESSEDKEY_BLOCK_SIZE=N
        KEY_BLOCK_SIZE目标压缩页大小(KB),常用 8/4/2
        通用表空间必须先设 FILE_BLOCK_SIZE(字节),且 KEY_BLOCK_SIZE = FILE_BLOCK_SIZE/1024
        参数互推写一个,另一个可自动推导
        最佳实践测试不同 KEY_BLOCK_SIZE,选择最优
        ⚠️ 注意大页(32KB/64KB)不支持压缩

        一句话建议

        如果你是普通用户,直接用 独立表空间 + KEY_BLOCK_SIZE=8 就够了;如果是 DBA 管理多个大表,可以考虑 通用表空间 + 统一压缩策略,但要严格遵守 FILE_BLOCK_SIZEKEY_BLOCK_SIZE 的匹配规则。

        到此这篇关于MySQL压缩表创建指南的文章就介绍到这了,更多相关mysql压缩表创建内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新数据库

        数据库排行榜