mysql优化-innodb表

mysql5.6参考手册读书笔记

优化INNODB表

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.

 优化innodb查询

优化innodb表的查询最有效的途径是创建合适的索引。那么如何创建合适的索引,以下是一些指导性的原则:
1、innodb表总是包含一个主键(如果没有指定主键,innodb自动帮你创建一个),innodb表数据的物理存储顺序和主键的顺序一致,所以选择一个合适的主键列至关重要,一般递增的值适合做innodb的主键。
2、innodb主键列会包含在其二级索引中,所以主键的列不宜太多或者不宜太大。大的主键会占用存储空间;当读取索引数据的时候要更多的io和缓存,这些多会影响性能。
3、没有必要为每一列创建索引,要结合表查询的场景来设计最有效的索引。
4、如果索引列不可能包含null值,就申明为not null。
5、在合适的场合使用查询缓存。

query_cache_type = 1
query_cache_size = 10M

优化Innodb系统变量

1、为Innodb配置高性能的内存分配器。
innodb在mem子系统中实现了一个自己的内存分配器,在硬件飞速发展,操作系统更新换代的环境下,这个分配器可能成为瓶颈。innodb通过在配置文件中指定变量 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的合并
purges 物理删除被标记为已删除的记录的操作所涉及的数据。
通过变量innodb_change_buffer_max_size设置change buffer的最大值(5.6.2及以后),该参数指定的值为change buffer占buffer pool的百分比,默认是25%,最大是50%。(支持运行时设置)

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之后无法立即执行的线程会被丢到一个先进先出的队列中,最终被执行。


 

 

 

 

 

你可能感兴趣的:(mysql)