首页 > 数据库 > > 8.5 优化 InnoDB 表
参考方法文档:
https://dev.mysql.com/doc/refman/5.7/en/optimizing-innodb.html
InnoDB是MySQL客户通常在可靠性和并发性非常重要的生产数据库中使用的存储引擎。 InnoDB是MySQL 5.7中的默认存储引擎。本节介绍如何优化InnoDB表的数据库操作。
8.5.1 为InnoDB表优化存储布局
OPTIMIZE TABLE复制表的数据部分并重建索引。 好处来自改进索引内的数据打包,减少表空间内和磁盘上的碎片。 好处取决于每个表中的数据。 您可能会发现某些人有显着的收益,有些没有,或者收益会随着时间的推移而下降,直到您再次优化表。 如果表很大或者重建的索引没有fit到buffer pool,则此操作可能会很慢。 在向表中添加大量数据之后的第一次运行通常比之后的运行慢得多。
在使用COMPACT行格式(默认InnoDB格式)和可变长度字符集(如utf8或sjis)时,CHAR(N)列占用可变的空间量,但仍至少为N个字节。
8.5.2 优化InnoDB事务管理
要优化InnoDB事务处理,请在事务功能的性能开销和服务器的工作负载之间找到理想的平衡点。 例如,如果应用程序每秒提交数千次,则应用程序可能会遇到性能问题,如果每2-3小时提交一次应用程序,则可能会遇到不同的性能问题。
--mysql 默认是自动提交的。
如果事务对数据库进行了修改,InnoDB必须在每次事务提交时将日志刷新到磁盘。 当每次更改之后都进行提交(与缺省自动提交设置一样)时,存储设备的I / O吞吐量将对每秒潜在操作的数量设置上限。
为了尽量减少发生此问题的机会:
为了摆脱发生的失控回滚,增加缓冲池,以便回滚成为CPU绑定并快速运行,或者终止服务器并使用innodb_force_recovery = 3重新启动。
在默认设置是innodb_change_buffering = all情况下,这种问题很少发生,它允许更新和删除操作被缓存在内存中,使得它们在第一时间执行起来更快,而且如果需要还可以更快地回滚。 确保在使用许多插入,更新或删除来处理长时间运行事务的服务器上使用此参数设置。
注意:
innodb_support_xa已弃用,将在未来版本中删除。 从MySQL 5.7.10开始,InnoDB对XA事务中的两阶段提交的支持始终处于启用状态,并且不再允许禁用innodb_support_xa。
---oracle 中是使用undo CR 块来保证一致性读的。
如果发现二级索引页面的PAGE_MAX_TRX_ID太新,或者二级索引中的记录被删除标记,则InnoDB可能需要使用聚簇索引来查找记录。
8.5.3 优化InnoDB只读事务
InnoDB可以避免与为已知为只读的事务设置事务ID(TRX_ID字段)相关联的开销。 只有可能执行写入操作或锁定读取的事务(如SELECT ... FOR UPDATE)才需要事务ID。 消除不必要的事务标识会减少每次查询或数据更改语句构造读取视图时查阅的内部数据结构的大小。
--DML 才会打开一个事务
目前,InnoDB在以下情况下检测只读事务:
ERROR 1792 (25006): Cannot execute statement in a READ ONLY transaction
您仍然可以在只读事务中更改特定于会话的临时表,或者为它们发出锁定查询,因为这些更改和锁对任何其他事务都是不可见的。
因此,对于读取密集型应用程序(例如报告生成器),可以通过将其分组到START TRANSACTION READ ONLY和COMMIT中,或者在运行SELECT语句之前打开自动提交设置,或者简单地通过避免 任何数据更改语句散布在查询中(查询中不要执行DML,读写分离)。
注意:
具有自动提交,non-locking 和 read-only (AC-NL-RO)资格的事务不在特定内部InnoDB数据结构中,因此未在SHOW ENGINE INNODB STATUS输出中列出。
8.5.4 优化InnoDB Redo Logging
考虑以下关于优化重做日志的指导原则:
使您的重做日志文件大,甚至与缓冲池一样大。 当InnoDB将重做日志文件写满时,它必须将修改后的缓冲池内容写入磁盘的检查点。 小的重做日志文件导致许多不必要的磁盘写入。 虽然历史上重要的重做日志文件会导致冗长的恢复时间,但现在恢复速度更快,您可以放心地使用大型重做日志文件。
重做日志文件的大小和数量使用innodb_log_file_size和innodb_log_files_in_group配置选项进行配置。
考虑增加日志缓冲区的大小。 大型日志缓冲区允许大型事务运行,而无需在事务提交之前将日志写入磁盘。 因此,如果您有更新,插入或删除多行的事务(大事务),则使日志缓冲区更大可节省磁盘I / O。 日志缓冲区大小是使用innodb_log_buffer_size配置选项配置的。
---innodb_log_buffer_size 建议设置大一点,对大型查询可以得到性能提升
8.5.5 为InnoDB 表批量加载数据
SET autocommit=0;
... SQL import statements ...
COMMIT;
mysqldump选项--opt创建快速导入到InnoDB表中的转储文件,即使没有用SET autocommit和COMMIT语句包装它们。
SET unique_checks=0;
... SQL import statements ...
SET unique_checks=1;
对于大型表,这节省了大量的磁盘I / O,因为InnoDB可以使用其更改缓冲区来批量写入二级索引记录。 确保数据不包含重复的key。
SET foreign_key_checks=0;
... SQL import statements ...
SET foreign_key_checks=1;
对于大表,这可以节省大量的磁盘I / O。
INSERT INTO yourtable VALUES (1,2), (5,5), ...;
这个适用于插入任何表,而不仅仅是InnoDB表。
--批量插入,而不是一个个insert 插入。
CREATE TABLE t1 (
FTS_DOC_ID BIGINT unsigned NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL DEFAULT ”,
text mediumtext NOT NULL,
PRIMARY KEY (`FTS_DOC_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE UNIQUE INDEX FTS_DOC_ID_INDEX on t1(FTS_DOC_ID);
注意:
在表创建时添加FTS_DOC_ID列时,请确保在更新FULLTEXT索引列时更新FTS_DOC_ID列,因为FTS_DOC_ID必须随每个INSERT或UPDATE单调递增。 如果您选择不在表创建时添加FTS_DOC_ID,并让InnoDB为您管理DOC ID,InnoDB将添加FTS_DOC_ID作为隐藏列,并进行下一个CREATE FULLTEXT INDEX调用。 但是,这种方法需要重建表格,这会影响性能。
8.5.6 优化 InnoDB 查询
要调整InnoDB表的查询,请在每个表上创建一组适当的索引。
[mysqld]
query_cache_type = 1
query_cache_size = 10M
--这个有点像 oracle result cache的意思
8.5.7 优化 InnoDB DDL 操作
8.5.8 优化 InnoDB 磁盘I/O
如果您遵循SQL操作的数据库设计和调优技术的最佳实践,但由于繁重的磁盘I / O活动,您的数据库仍然很慢,请考虑这些磁盘I / O优化。 如果Unix顶级工具或Windows任务管理器显示工作负载的CPU使用百分比低于70%,那么您的工作负载可能是磁盘限制的。
当表数据缓存在InnoDB缓冲池中时,可以通过查询重复访问它,而不需要任何磁盘I / O。 用innodb_buffer_pool_size选项指定缓冲池的大小。 此内存区域非常重要,通常建议将innodb_buffer_pool_size配置为系统内存的50%到75%。
--这就是 oracle 的buffer cache
在GNU / Linux和Unix的某些版本中,使用Unix fsync()调用(InnoDB默认使用)和类似方法将文件清理到磁盘的速度惊人地慢。 如果数据库写入性能出现问题,请使用设置为O_DSYNC的innodb_flush_method参数进行基准测试。
在任何Solaris 2.6或更高版本以及任何平台(sparc / x86 / x64 / amd64)上使用innodb_buffer_pool_size值较大的InnoDB存储引擎时,应在InnoDB数据文件和日志文件的原始设备或单独的 direct I/O UFS文件系统,使用前面所述的forcedirectio挂载选项。 (如果需要对日志文件进行 direct I/O,则必须使用安装选项而不是设置innodb_flush_method。)Veritas文件系统VxFS的用户应使用convosync = direct mount选项。
不要将其他MySQL数据文件(如MyISAM表格的数据文件)放在 direct I/O文件系统上。 可执行文件或库不能放在 direct I/O文件系统上。
非循环存储通常为随机I/O操作提供更好的性能(SSD); 旋转存储是为了顺序I/O操作。 在通过旋转和非旋转存储设备分发数据和日志文件时,请考虑主要在每个文件上执行的I/O操作的类型。
随机的面向I / O的文件通常包括file-per-table和一般表空间数据文件,undo表空间文件和临时表空间文件。 顺序I / O的文件包括InnoDB系统表空间文件(由于写入缓冲和更改缓冲)和日志文件(如二进制日志文件和重做日志文件)。
使用非循环存储时,请查看以下配置选项的设置:
crc32选项使用更快的校验和算法,推荐用于快速存储系统。
该选项优化了旋转存储设备的I / O。 禁用它用于非旋转存储或混合旋转和非旋转存储。
对于较低端的非旋转存储设备,默认设置200通常是足够的。 对于更高端的总线连接设备,考虑更高的设置,如1000。
默认值2000适用于使用非旋转存储的工作负载。 对于高端,总线连接的非旋转存储设备,考虑更高的设置,如2500。
如果重做日志位于非循环存储中,请考虑禁用此选项以减少日志记录
---此参数确定是否记录压缩页面的一个日志
如果重做日志位于非循环存储中,请配置此选项以最大化高速缓存和写入组合。
考虑使用与磁盘的内部扇区大小相匹配的页面大小。 早期的SSD设备通常具有4k扇区大小。 一些较新的设备具有16k扇区大小。 InnoDB的默认页面大小是16k。 保持页面大小接近存储设备块大小可将重写到磁盘的未更改数据量减至最少。
如果二进制日志位于非循环存储中,并且所有表都有主键,请考虑将此选项设置为最小以减少日志记录。
确保为您的操作系统启用TRIM支持。 它通常默认启用。
如果由于InnoDB检查点操作导致吞吐量周期性下降,请考虑增加innodb_io_capacity配置选项的值。 更高的值会导致更频繁的刷新,避免可能导致吞吐量下降的工作积压。
如果系统不落后于InnoDB刷新操作,请考虑降低innodb_io_capacity配置选项的值。 通常情况下,您保持该选项的值尽可能低,但不能太低,以致导致吞吐量的周期性下降,如前面的项目符号所述。 在可以降低选项值的典型场景中,您可能会在SHOW ENGINE INNODB STATUS的输出中看到类似这样的组合:
通过在支持原子写入的Fusion-io设备上存储系统表空间文件(“ibdata文件”),您可以利用与双写缓冲区相关的I / O优化。 在这种情况下,自动禁用双写缓冲(innodb_doublewrite),并将Fusion-io原子写入用于所有数据文件。 此功能仅在Fusion-io硬件上受支持,并且仅适用于Linux上的Fusion-io NVMFS。 要充分利用此功能,建议使用innodb_flush_method设置O_DIRECT。
注意:
由于双写缓冲区设置是全局性的,所以对于驻留在非Fusion-io硬件上的数据文件,也会禁用双写缓冲。
使用InnoDB表格压缩功能时,当对压缩数据进行更改时,重新压缩页面的image将写入重做日志。 此行为由innodb_log_compressed_pages控制,该行为默认情况下已启用,以防止在恢复过程中使用不同版本的zlib压缩算法时可能发生的损坏。 如果您确定zlib版本不会更改,请禁用innodb_log_compressed_pages以减少修改压缩数据的工作负载的重做日志生成。
--这个参数是可以禁用的,如果不进行版本变化的话。
8.5.9 优化 InnoDB 配置变量
因为InnoDB存储引擎会自动执行许多优化,所以许多性能调优任务都涉及监控,以确保数据库性能良好,并在性能下降时更改配置选项。
参考 Section 14.16, “InnoDB Integration with MySQL Performance Schema” 关于性能监控部分
您可以执行的主要配置步骤包括:
8.5.10 为具有多个表的系统优化InnoDB
如果配置了非持久性优化器统计信息(非默认配置),则InnoDB会在启动后第一次访问表时计算表的索引基数值,而不是将这些值存储在表中。 在将数据分成许多表的系统上,这一步可能需要很长时间。 由于此开销仅适用于初始表打开操作,要“预热”表供以后使用,请在启动后立即通过发出诸如SELECT 1 FROM tbl_name LIMIT 1之类的语句来访问它。
优化器统计信息默认保存到磁盘,由innodb_stats_persistent配置选项启用。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69946831/viewspace-3137562/ ,如需转载,请注明出处,否则将追究法律责任。