您的位置:首页 > 数据库 > MySQL

mysql5.7官网直译InnoDB表优化--行存储布局,事物管理

2017-12-11 15:43 295 查看
8.5 Optimizing for InnoDB Tables 关于InnoDB表的优化

8.5.1 Optimizing Storage Layout for InnoDB Tables 关于InnoDB表存储布局的优化

8.5.2 Optimizing InnoDB Transaction Management InnoDB 事物管理的优化

8.5.3 Optimizing InnoDB Read-Only Transactions InnoDB 只读事物的优化

8.5.4 Optimizing InnoDB Redo Logging Redo InnoDB Redo日志的优化

8.5.5 Bulk Data Loading for InnoDB Tables 关于InnoDB表的数据块的加载

8.5.6 Optimizing InnoDB Queries InnoDB查询的优化

8.5.7 Optimizing InnoDB DDL Operations InnoDB的DDL操作的优化

8.5.8 Optimizing InnoDB Disk I/O InnoDB磁盘I/O的优化

8.5.9 Optimizing InnoDB Configuration Variables InnoDB配置变量的优化

8.5.10 Optimizing InnoDB for Systems with Many Tables InnoDB系统中多表优化

InnoDB是一个mysql客户在生产环境中使用数据库的存储引擎,其稳定而且支持并发。InnoDB也是MySQL默认的存储引擎。这一部分会介绍怎么样优化数据库操作关于InnoDB表。

--------------------------------------

8.5.1 Optimizing Storage Layout for InnoDB Tables 关于InnoDB表存储布局的优化

>只要你的数据达到一个稳定的大小,或者表的增长都是通过10或者百兆字节大小,考虑使用OPTIMIZE TABLE语句来重组表并减少任何浪费的表空间。重组后的表需要更少的磁盘I/O来完成全表扫描。这是一个直接了当的技术能够提高性能,当其他技术比方说提高索引使用率或者是说修改应用代码不现实时可以使用。

OPTIMIZE TABLE复制表中的数据部分并且重构索引。好处是索引和数据放一起,并且减少了表空间的碎片。好处的多少依赖于每张表中的数据。你可能会发现有些有明显改善,有些则无效果,或者是有些没啥效果直到你优化了其他表。这操作可能会耗时,如果表很大或者是索引重构不能放入缓存中完成的话。在添加大量数据之后的表中首次运行通常比最近一次运行要慢许多。

>在InnoDB,有一个长主键(要么是一列但是值很长,或者是多列形成一个很长的复合值)会浪费许多磁盘空间。一行中的主键值会被复制到所有的二级索引记录中指向相同的行。(具体请看14。8.2.1的集群和二级索引)创建一个洞增长的列作为一个主键,如果你的主键很长的话,或者是使用很长列的一部分前缀来索引来代替整个列。

>使用VARCHAR类型来代替CHAR类型来存储可变长度的字符串或者是列中会有很多Null值的情况。一个CHAR(N)列总是占用N个字符的存储空间,即使字符串很短或者是值就是null。表越小越容易放入缓存并且减少磁盘I/O.

当使用紧凑行格式(InnoDB的默认格式)和变长字符集,例如utf8或者sjis,CHAR(N)列占据可变的空间,但是至少需要Nbytes。

>对于大表,或者是包含大量重复文本或者数字数据,考虑使用COMPRESSED行格式。更少的磁盘I/O就可以将数据带入缓存池,或是完成全表扫描。在做一个永久决定之前,通过对比使用COMPRESSED和COMPACT两种格式可以达到的效果,从而决定采用哪种方式更好。

--------------------------------------

8.5.2 Optimizing InnoDB Transaction Management 优化InnoDB事物管理

为了优化InnoDB事物处理,找出理想的平衡点在事物特性的性能开销和服务的工作负载之间。例如,一个应用可能遇到了性能问题,因为他每秒有数千次的提交,并且不同的性能问题,如果它每两三个小时才提交。

>mysql的默认设置是AUTOCOMMIT=1能够局限性能在一个繁忙的服务器。然而事实上,包裹着多个相关数据的改变操作在一个单一事物中,通过声明设置AUTOCOMMIT=0 或者是一个开始事物语句,然后在所有改变操作之后跟着一个COMMIT语句。

InnoDB必须刷出日志到磁盘对每一个事物提交如果事物修改了数据库的话。当每一个改变都跟着一个提交(就像默认的设置),那么I/O吞吐率对每秒潜在的操作次数有一个上限。

>另外,对于只有一个简单的查询语句组成的事物,通过AUTOCOMMIT帮助InnoDB识别只读事物并且优化他们。具体请看8.5.3的对只读事物优化的要求。

>在插入,修改,删除大量行之后,尽量避免回滚。如果一个大事物使得服务变慢,那么回滚会使得情况变的更糟糕,潜在的花费一些时间来恢复成原数据。杀死数据库进程也没有帮助,因为回滚会在服务启动时再次开始。

为了降低遇到这种情况的记录:

  1)增加缓冲池的大小,从而保证所有的数据改变可以被缓存,而不是直接写入磁盘

  2)设置innodb_change_buffering=all,从而保证更新或是删除操作被缓存在额外的插入操作。

  3)定期的通过大数据操作来考虑COMMIT语句的问题,可以分开一个单一删除或更新到多个语句操作,每一个都只操作少量的几行数据。

为了拜托失控的回滚,万一发生的话,增加缓存池使得回滚变的cpu受限并且运行快速,或者是杀掉服务,并且重启通过innodb_force_recovery=3,具体请看14.18.2的InnoDB的恢复。

这个问题希望通过设置innodb_change_buffering=all来减少出现的情况,允许更新和删除操作被缓存,使得他们被快速的执行,如果需要回滚也可以快速回滚。为了能使用这个参数设置在服务器,将长时间的事物切分为多个插入,更新和删除。

>如果发生意外,你能够容忍丢失一些最近的事物提交,你能设置innodb_flush_log_at_trx_commt参数为0.innoDB会试着每秒刷新一次日志,但是刷新是没有保证的。也就是说,设置了innodb_support_xa值为0,将会减少刷新磁盘次数,用于同步磁盘数据和二进制日志。

    注意:

    innodb_support_xa是过期参数,并且将会被移除在未来的版本中。就mysql5.7.10,innoDB支持两阶提交在XA事物是可用的,并且不可用的innodb_support_xa将不在被允许。

>当行被修改或者删除,行数据和关联的undo日志不是理解被物理移除,或者是在事物提交后也不会。老数据被保护直到最早开始的事物或者当前事物已经完成,所以这些事物能够访问修改之前的行的状态。这样,一个长时间运行的事物能够阻止InnoDB清洗那些已经被不同事物修改的数据。

>当在一个很长的事物中修改或者删除行,其他事物使用READ_COMMITTED和REPEATABLE_READ事物级别不得不做更多的工作重构老数据,如果他们读取的刚好是相同的数据的话。

>当一个长时间运行的事物修改了表,另一个事物访问该表不能使用覆盖索引。查询正常情况下可以通过二级索引查询到所有想要的结果,而不需要从表中的数据查询想要的结果。

如果被发现的二级索引页中有一个PAGE_MAX_TRX_ID是特别新的,或者是在二级索引中的记录以及被标记为删除,innoDB会需要查找记录使用一个聚簇索引。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息