MySQL版本:8.0.22

os:linux ubuntu

语言:c++、c

在MySQL中支持3种类型的表压缩,依次为:传统压缩、TPC压缩、字典压缩。

第一种:传统压缩

传统的表压缩方式是在MySQL5.0.7之前使用的,现在已经废弃了,因为这种方式不但没有提升数据库的效率,反而降低了效率,导致buffer pool的使用率降低了。

create table时指定压缩后表的大小,即 KEY_BLOCK_SIZE 的大小,page默认大小为16KB。压缩是按page为单位进行压缩的。

SQL语句:

create table tt
(c1 int primary key,c2 varchar(50)
) engine = innodb KEY_BLOCK_SIZE=8; KEY_BLOCK_SIZE 的取值为: 1,2,4,8,16

表示一个16KB的page压缩之后是8KB。如果一个page压缩之后的大小为9KB,那么需要2个8KB的page进行存储。如果一个page压缩之后的大小为6KB,那么只需要1个8KB的page进行存储即可。

KEY_BLOCK_SIZE的大小可以是 1、2、4、8、16,表示启用页压缩,然后按照 1K、2K、4K、8K、16K 的页大小存储数据。如果设置KEY_BLOCK_SIZE的大小为0,那么MySQL自动的将KEY_BLOCK_SIZE设置为innodb_page_size/2;

缺点:一个页在缓冲池中存在两个版本,压缩前的原始版本和压缩后的版本,这样导致缓冲池中能缓存page页的数量大大减少,在buffer pool中多产生一个page。对于一个16KB的page,一个存放的是原来的16KB的页数据,另一个是压缩后的page,压缩后以8KB为例,8KB中存放的是压缩后的数据再加上redo.log日志以及file header和file tailer部分。

因此,这种压缩方式会额外的多占用一个page用于存储压缩之后的page。

参考:MySQL :: MySQL 8.0 Reference Manual :: 15.9.1.2 Creating Compressed Tables

第二种:TPC压缩

TPC是Transparent page compression的简称,也就是 透明页压缩。这种方式是主流的压缩方式。

压缩是按page为单位进行压缩的,一个page的大小默认是16KB,也就是innodb page的默认大小,用于可以通过SQL : select @@innodb_page_size;查询page的大小;下面都采用一个page为16KB为单位。

SQL语句:

create table tt
(c1 int primary key,c2 varchar(128)
) engine = innodb compression=zlib;create table tt
(c1 int primary key,c2 varchar(128)
) engine = innodb compression=lz4;create table tt
(c1 int primary key,c2 varchar(128)
) engine = innodb compression=none;

建表时,compression=后面指定压缩的方式,支持下面3种写法:

COMPRESSION [=] {'ZLIB' | 'LZ4' | 'NONE'}

其中zlib和lz4是支持的压缩方式,NONE表示不压缩。

一个page变成dirty page之后,后台线程就会将该dirty page flush到磁盘文件中。确定要flush到磁盘文件时,先将该page进行压缩(lz4/zlib),压缩之后以9KB为例,那么剩余的7KB(16K-9K)就会被填充为0x00,然后flush到磁盘文件后,调用文件系统空洞(Hole Punch)特性(实际上是fallocate())对文件进行“裁剪”,释放 0x00 占用的稀疏空间,实际存放到磁盘上的文件大小为7KB。

当前linux的内核以及大部分的文件系统,例如:XFS、EXT4、ZFS、btrfs、NTFS 等,都支持文件空洞特性。

查看压缩后的文件占用的存储空间大小的SQL如下:

SELECT SPACE, NAME, FS_BLOCK_SIZE, FILE_SIZE, ALLOCATED_SIZE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME='mysql/bmsql_customer';

FILE_SIZE:表示原始文件的大小

ALLOCATED_SIZE:表示压缩之后的大小

压缩率 = ALLOCATED_SIZE / FILE_SIZE

参考:MySQL :: MySQL 8.0 Reference Manual :: 15.9.2 InnoDB Page Compression

第三种:字典压缩

基于字典的列压缩又叫压缩字典,但只适用于Percona分支。
优点是压缩率高, 每个列的数据类型都相同;

限制条件:
该列压缩方式仅用于InnoDB/XtraDB存储引擎,数据类型支持:
(1)、BLOB (including TINYBLOB, MEDIUMBLOB, LONGBLOG)
(2)、TEXT (including TINYTEXT, MEDUUMTEXT, LONGTEXT)
(3)、VARCHAR (including NATIONAL VARCHAR)
(4)、VARBINARY
(5)、JSON
应用于不受支持的列类型或存储引擎,则会报错。

使用MySQL自带的压缩键功能时的SQL语句:
在创建表语句或更改表语句中增加压缩标识
(1)、CREATE语句

CREATE TABLE ... (..., foo BLOB COLUMN_FORMAT COMPRESSED, ...);

(2)、ALTER语句

ALTER TABLE ... CHANGE [COLUMN] ... COLUMN_FORMAT COMPRESSED;ALTER TABLE ... MODIFY [COLUMN] ... COLUMN_FORMAT COMPRESSED;

还有一种是用户自定义压缩键,也就是在在建表时指定压缩和压缩键。

SQL语句如下:

SET @dictionary_data = 'wall' 'apple' 'peach' 'orange';CREATE COMPRESSION_DICTIONARY numbers (@dictionary_data);CREATE TABLE tt(c1 INT,c2 text COLUMN_FORMAT COMPRESSED,c3 BLOB COLUMN_FORMAT COMPRESSED WITH COMPRESSION_DICTIONARY numbers) ENGINE=InnoDB;

c2采用MySQL默认的压缩键;

c3采用用户自定义的压缩键;

不过这种方式使用起来还是有争议的,如果用户用不好压缩键导致压缩率低。

其他参考文献:MySQL :: MySQL 8.0 Reference Manual :: 13.1.20 CREATE TABLE Statement

总之:

现在主流的压缩方式为:TPC压缩和基于字典键的压缩。

如有疑问请发邮件:zgaoq@163.com

MySQL中的表压缩功能相关推荐

  1. mysql中单个表脏读_如何在Outlook中单击邮件后立即将其标记为已读

    mysql中单个表脏读 Do you ever feel annoyed that Outlook doesn't mark messages as read as soon as you click ...

  2. mysql中为表增加外键_如何在Excel 2013中为符号分配键盘快捷键

    mysql中为表增加外键 We've previously shown you how to add keyboard shortcuts to symbols in Word 2013 to mak ...

  3. mysql中dual表

    1.楔子 今日在某项目数据库中发现每个库底下都有这样一张表,如下图所示: 这张表有且只能有一条数据,表结构如下所示: 我想这样做必然有其精神奥义和奇技淫巧,于是一探究竟. 2. mysql中模拟dua ...

  4. mysql中修改表的默认编码和表中字段的编码

    ALTER TABLE `table` DEFAULT CHARACTER SET utf8; 但是虽然修改了表的编码格式,但是字段的编码格式并没有修改过来,没有什么卵用 又发现一条语句,作用是修改字 ...

  5. mysql 如何删除重复的行_如何从mysql中的表中删除重复的行

    我需要从 mysql中删除表中的重复记录. 所以我有一个表名"employee"字段是empid,empname,empssn 为了获得重复记录我写了一个查询 SELECT COU ...

  6. mysql导出oracle_如何将mysql中的表结构导出放入oracle中

    展开全部 将mysql中的表结构导出放入oracle中的方法: 1.导出mysql的表结构sql脚本,然后修改mysql中的数据类型为oracle中的数据类型: MySql与Oracle数据类型的62 ...

  7. mysql join 组合索引,图文详解MySQL中两表关联的连接表如何创建索引

    本文介绍了MySQL中两表关联的连接表是如何创建索引的相关内容,分享出来供大家参考学习,下面来看看详细的介绍: 问题介绍 创建数据库的索引,可以选择单列索引,也可以选择创建组合索引. 遇到如下这种情况 ...

  8. MySQL中竖表和横表之间的相互转换

    MySQL中竖表和横表之间的相互转换 1.  横表转为竖表 表tb的结构为 表中的数据为 现在要求查询到如下结果 使用的SQL查询语句应该如下: 或者使用下面查询 2.  竖表转为横表 tb2表的结构 ...

  9. mysql中自增auto_increment功能的相关设置及问题

    1. mysql中的自增auto_increment功能相信每位phper都用过,本文就为大家分享一下mysql字段自增功能的具体查看及设置方法 mysql中的自增auto_increment功能相信 ...

最新文章

  1. Mysql 内置函数
  2. php gd库画线,[PHP] GD库(十)绘制线段与圆弧 imageline、imagesetstyle 与 imagearc 函数...
  3. python获取当前脚本所在路径并在此基础上创建新的文件路径
  4. 银行家算法 计算机操作系统,计算机操作系统 银行家算法.doc
  5. 软件之美: 易用性设计的目标及准则
  6. MathType初体验——一款很好用的数学公式输入工具
  7. 接口测试用例设计 - 精简版
  8. jmeter分布式部署
  9. 车路协同科研教学与实训先导平台 ——一种面向新一代智能交通人才培养的综合实验平台及系统
  10. python 语言基本知识2:数据结构
  11. Apache的域名配置
  12. 磨金石教育摄影技能干货分享|近景拍摄技巧分析
  13. 开发的页面卡顿、慢?一文教你如何进行页面性能优化
  14. 学习计算机的英语口语,最实用的英语口语学习技巧
  15. STM32F103xx OLED旋转显示图片
  16. java最简单的代码
  17. MEM/MBA 英语强化(01)完形填空
  18. Win11 右键风格改为 Win10风格
  19. cannot find package “github.com/PuerkitoBio/goquery“ in any of
  20. C语言 不使用strcpy 函数实现字符串复制功能

热门文章

  1. 诺基亚收购了阿朗:那与 TCL 的“阿尔卡特”品牌授权协议到期后咱办?
  2. Kafka官方文档翻译——实现
  3. node.js 实现扫码二维码登录
  4. 如何对web.config进行加密和解密
  5. Ios: 如何保護iOS束文件屬性列表,圖像,SQLite,媒體文件
  6. linux文件的时间格式
  7. DEDE 会员调用方法详解
  8. 增加表单的文字段的html的代码是,表单及表单新增元素(示例代码)
  9. linux 命令 which whereis whatis locate find
  10. python2.7无法使用pip(安装easy_install)