我最近开始使用允许压缩的Barracuda InnoDB / MySQL表格式。
我通过运行来压缩我的一个表格:
alter table pricing row_format=compressed, key_block_size=8;
在我运行这个之后,我查看了压缩数据(我已经在ALTER TABLE之前清除了它们):
mysql> select * from INFORMATION_SCHEMA.INNODB_CMP; + ----------- -------------- + + ----------------- + ---- ----------- + ---------------- + ----------------- + | page_size | compress_ops | compress_ops_ok | compress_time | uncompress_ops | uncompress_time | + ----------- -------------- + + ----------------- + ---- ----------- + ---------------- + ----------------- + | 1024 | 0 | 0 | 0 | 0 | 0 | | 2048 | 0 | 0 | 0 | 0 | 0 | | 4096 | 0 | 0 | 0 | 0 | 0 | | 8192 | 7029231 | 6352315 | 1437 | 339708 | 41 | | 16384 | 0 | 0 | 0 | 0 | 0 | + ----------- -------------- + + ----------------- + ---- ----------- + ---------------- + ----------------- + 5行(0.00秒) mysql> select * from INFORMATION_SCHEMA.INNODB_CMPMEM; + ----------- ------------ + ------------ + + ----------- ----- + ----------------- + | page_size | pages_used | pages_free | relocation_ops | relocation_time | + ----------- ------------ + ------------ + + ----------- ----- + ----------------- + | 128 | 11214 | 0 | 8434571 | 2 | | 256 | 0 | 37 | 0 | 0 | | 512 | 0 | 34 | 0 | 0 | | 1024 | 0 | 2 | 0 | 0 | | 2048 | 0 | 141 | 0 | 0 | | 4096 | 0 | 298 | 96657 | 0 | | 8192 | 15133 | 0 | 4121178 | 5 | | 16384 | 0 | 0 | 0 | 0 | + ----------- ------------ + ------------ + + ----------- ----- + ----------------- + 设置8行(0.00秒)
如果我用compress_ops分割compress_ops_ok,那就是6352315/7029231 = 90.4%。 我的理解是,基本上90.4%的页面从16KB压缩到8KB,其余的不能压缩2倍。
我已经读过这些压缩失败的页面会伤害性能,但成功压缩的90%以上应该会提高性能(通过降低I / O操作)。 是否有一个经验法则的页面应压缩多less百分比,这被认为是好的? 我的其他select可能是只是禁用压缩。
我的目标是减lessI / O操作的数量,如果这样做会适得其反,我不希望压缩。
即使在运行压缩之后,您仍可能无法获得所需的性能。 为什么?
InnoDB拥有缓冲池来读取数据页面和索引页面来完成查询。 当首次读取表及其索引时,压缩的页面必须是未压缩的。 实际上,由于这个原因,缓冲池中的数据可能会增加两倍。
请注意MySQL文档中的情况
压缩和InnoDB缓冲池
在压缩的InnoDB表中,每个压缩页面(无论是1K,2K,4K还是8K)对应于16K字节的未压缩页面。 为了访问页面中的数据,InnoDB从磁盘读取压缩的页面(如果该页面不在缓冲池中),然后将页面解压缩为原来的16K字节forms。 本节介绍InnoDB如何pipe理与压缩表页面相关的缓冲池。
为了尽量减lessI / O并减less解压缩页面的需要,缓冲池有时包含压缩和未压缩的数据库页面forms。 为了给其他需要的数据库页面腾出空间,InnoDB可能会从缓冲池中“驱逐”一个未压缩的页面,同时将压缩的页面留在内存中。 或者,如果页面在一段时间内没有被访问,页面的压缩forms可能被写入磁盘,为其他数据腾出空间。 因此,在任何给定的时间,缓冲池可以包含页面的压缩和未压缩forms,或者只包含页面的压缩forms,或者既不包含压缩forms。
InnoDB跟踪哪些页面保留在内存中,哪些使用最近最less使用(LRU)列表驱逐,以便“热”或频繁访问的数据往往留在内存中。 当访问压缩表时,InnoDB使用自适应LRUalgorithm来实现内存中压缩和未压缩页面的适当平衡。 这种自适应algorithm对系统是以I / O绑定方式还是CPU绑定方式运行很敏感。 我们的目标是避免在CPU繁忙时花费太多的处理时间来解压缩页面,并且避免在CPU有可用于解压缩压缩页面(可能已经在内存中)的空闲周期时执行多余的I / O操作。 当系统被I / O绑定时,algorithm更倾向于驱逐页面的未压缩副本而不是两个副本,以使其他磁盘页面成为内存驻留的更多空间。 当系统受到CPU限制时,InnoDB更喜欢将压缩和未压缩的页面逐出,这样可以将更多的内存用于“热”页面,并且减less了仅以压缩forms解压缩内存中的数据的需要。
如果数据内容的重复正在缓冲池中进行,则需要将innodb_buffer_pool_size增加一个新的压缩率的小线性因子。 这里是如何:
key_block_size=8运行压缩
8是16 50.00% 8G 50.00%是4G innodb_buffer_pool_size提高到12G ( 8G + 4G ) key_block_size=4运行压缩
4是16 25.00% 8G 25.00%是2G innodb_buffer_pool_size提高到10G ( 8G + 2G ) key_block_size=2运行压缩
2是16 12.50% 8G 12.50%是1G innodb_buffer_pool_size提高到9G ( 8G + 1G ) key_block_size=1运行压缩
1是16 06.25% 8G 06.25%是0.5G ( 512M ) innodb_buffer_pool_size提高到8704M ( 8G ( 8192M )+ 512M ) 故事的道理 :InnoDB缓冲池在处理压缩数据和索引页面时只需要额外的喘息空间。
这个数据是从一个ALTER TABLE中获得的,这是一个你不经常使用的语句,它重写了整个表。 重要的是您的日常工作量,即您的应用程序在生产环境中执行的所有插入和更新。 根据MySQL手册:
“您可能会closures表压缩,导致您的应用程序中”压缩失败“数量超过总数的1%或2%(这样的失败率在临时操作中可能是可以接受的,例如数据负载)“。