mysql5.6参考手册读书笔记
innodb存储引擎是mysql5.6默认的存储引擎。
1、当表的大小趋于稳定或者表大小经过了急速的增长,应该使用OPTIMIZE TABLE语句优化表的存储结构。
2、大的主键浪费空间,因为innodb表的主键会存储在每一个二级索引中。
3、使用varchar来定义存储变长字符串的列或者包含许多null值的列。这里主要是为了尽量缩减表的大小,因为小表可以装进缓存,减少IO操作。
4、对于大表或者包含很多数字或者重复字符的表,尝试使用ROW_FORMAT=COMPRESSED行存储格式。(小表万岁)
从mysql5.6.4开始,对于只读事务不再分配事务id(TRX_ID).消除不必要的事务ID可以优化构建一致性视图的开销。
1、使用大的重做日志文件(甚至可以和buffer pool一般大)。当innodb存储引擎写满重做日志后,会触发buffer pool把脏数据写到磁盘上。小的重做日志文件会引发很多不必要的写磁盘操作。
重做日志文件的大小及文件的数量分布由innodb_log_file_size和innodb_log_files_in_group
配置。
大的重做日志文件会增加数据库恢复的时间,但总的来说还是会很快。
2、考虑增大重做日志缓存(log_buffer).大的log_buffer可以使大的事务在提交之前都不用把日志写到磁盘上,减少了执行期间的io操作。大的日志缓存会增加数据库丢失数据的风险。每一次commit操作都会触发把log_buffer中的日志刷新到磁盘日志文件中。
log_buffer的大小由innodb_log_buffer_size
配置。
1、关闭autocommit。因为每次commit都会触发刷新重做日志缓存到磁盘日志文件的操作。
2、对于二级索引,禁掉唯一约束检查。
3、禁掉外键约束。
4、使用INSERT INTO yourtable VALUES (1,2), (5,5), ...;句型
5、往包含自增列的表插数据应该设置innodb_autoinc_lock_mode
=2,默认值为1.
query_cache_type = 1 query_cache_size = 10M
innodb_use_sys_malloc
来控制innodb使用自带的内存分配器还是操作系统的内存分配器(运行时修改无效)。当设置
innodb_use_sys_malloc=1时,变量innodb_additional_mem_pool_size无效。
这两个变量在mysql5.6.3已不推荐使用,在5.7.4中被删除。
2、设置change buffer
当在一个表上执行insert,update或者delete时,通常修改的索引列的值是无序的,当被修改的页不在buffer pool里边时,需要代价颇高的随机IO来更新索引。为了避免这种随机的IO操作,Innodb提供一个change buffer来缓存这种数据,避免立即读取索引页进行更新。当change buffer中的数据页被读取到buffer pool中时,在服务器主线程空闲的时候或者正常关机的时候再进行一个合并,最后把数据刷新到磁盘。
change buffer是buffer pool的一部分。如果所需要的数据全部都在buffer pool中或者二级索引比较少,那么change buffer的作用不大,可以禁掉。因为change buffer只会缓存被修改的索引数据,且该数据所在的页不在buffer pool中。
通过变量innodb_change_huffering变量配置change buffer来缓存不同的数据,可选值如下:(支持运行时设置)
all 默认值。缓存insert,delete,purges(删除已被标记为删除的记录)。update操作相当于一个insert紧接一个delete。
none 不缓存数据
inserts 仅缓存insert操作涉及的数据
deletes 缓存标记删除操作涉及的数据
changes inserts和deletes的合并
3、配置自适应哈希索引
自适应哈希索引使innodb存储引擎像myisam引擎一样使用hash索引来做表连接。
使用innodb_adaptive_hash_index变量打开或者关闭自适应hash索引功能,默认值为on,表示开启。或者在启动服务器的时候使用--skip_innodb_adaptive_hash_index选项来关闭自适应hash索引。
innodb本身并不支持hash索引,而是在某些时候通过B树索引前缀在内存中构建一个hash索引,以提高查询性能。这个过程对用户是透明的。
4、并发控制
innodb使用操作系统线程来处理用户发起的事务(一个事务可以包含多个线程)。在现代多核CPU环境下,线程切换变得越发高效,很多情况下不需要再限制并发的线程数。
当需要减少线程上下文切换以提高性能时,innodb支持限制当前正在执行的线程数量。当innodb接收到来自客户端的新的请求时,innodb会检查目前正在执行的线程数是否超过了innodb_thread_concurrency设定的值,如果超出了则新的线程会sleep一段时间(innodb_thread_sleep_delay)后再试(正在等待锁的线程不算作正在执行的线程数中),sleep之后无法立即执行的线程会被丢到一个先进先出的队列中,最终被执行。