mysql的配置参数中,有的是指明全局的内存使用大小,有的是配置单个线程的内存大小。
在mysql优化几点注意中我们提到了几个全局内存使用的参数和一个bulk_insert_buffer_size线程级配置的参数。下面补充学习一下这些参数。
------------------------------全局内存使用---------------------------
query_cache_size[global]
查询缓存是MySQL 比较独特的一个缓存区域,用来缓存特定Query 的结果集(Result Set)信息,且共享给所有客户端。通过对Query 语句进行特定的Hash 计算之后与结果集对应存放在Query Cache 中,以提高完全相同的Query 语句的相应速度。当我们打开MySQL 的Query Cache 之后,MySQL 接收到每一个SELECT 类型的Query 之后都会首先通过固定的Hash 算法得到该Query 的Hash 值,然后到Query Cache 中查找是否有对应的Query Cache。如果有,则直接将Cache 的结果集返回给客户端。如果没有,再进行后续操作,得到对应的结果集之后将该结果集缓存到Query Cache 中,再返回给客户端。当任何一个表的数据发生任何变化之后,与该表相关的所有Query Cache 全部会失效,所以Query Cache 对变更比较频繁的表并不是非常适用,但对那些变更较少的表是非常合适的,可以极大程度的提高查询效率,如那些静态资源表,配置表等等。为了尽可能高效的利用QueryCache,MySQL 针对Query Cache 设计了多个query_cache_type 值和两个Query Hint:SQL_CACHE 和SQL_NO_CACHE。当query_cache_type 设置为0(或者OFF)的时候不使用Query Cache,当设置为1(或者ON)的时候,当且仅当Query 中使用了SQL_NO_CACHE 的时候MySQL 会忽略Query Cache,当query_cache_type 设置为2(或者DEMAND)的时候,当且仅当Query 中使用了SQL_CACHE 提示之后,MySQL 才会针对该Query 使用Query Cache。可以通过query_cache_size 来设置可以使用的最大内存空间。
thread_cache_size[global]
把thread_cache_size这个参数列在这里,其实这个参数并不是定义内存大小的。而是定义缓存了的线程数量。
table_open_cache[global]
打开表的缓存数量。也不是定义内存的大小的。而是定义可以缓存多少打开的表的文件句柄信息。如果定义的太小,那么mysql在需要打开新表的时候就要不断的关闭已经打开的表和打开此次需要打开的表。性能会受到影响。
table_definition_cache[global]
表定义信息缓存是从MySQL5.1.3 版本才开始引入的一个新的缓存区,用来存放表定义信息。当我们的MySQL 中使用了较多的表的时候,此缓存无疑会提高对表定义信息的访问效率。MySQL 提供了table_definition_cache 参数给我们设置可以缓存的表的数量。在MySQL5.1.25 之前的版本中,默认值为128,从MySQL5.1.25 版本开始,则将默认值调整为256 了,最大设置值为524288。注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。表定义信息缓存是从MySQL5.1.3 版本才开始引入的一个新的缓存区,用来存放表定义信息。当我们的MySQL 中使用了较多的表的时候,此缓存无疑会提高对表定义信息的访问效率。MySQL 提供了table_definition_cache 参数给我们设置可以缓存的表的数量。在MySQL5.1.25 之前的版本中,默认值为128,从MySQL5.1.25 版本开始,则将默认值调整为256 了,最大设置值为524288。注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。
------------------------------线程局部内存使用---------------------
join_buffer_size[thread]
应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/index join),为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作【将被驱动表的数据分批读取到join buffer,然后进行join操作,具体可以参见这里】。当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join 的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。
read_buffer_size[thread]
这部分内存主要用于当需要顺序读取数据的时候,如无法使用索引的情况下的全表扫描,全索引扫描等。在这种时候,MySQL 按照数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在read_buffer_size中,当 buffer 空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调用者,以提高效率。
read_rnd_buffer_size[thread]
和顺序读取相对应,当 MySQL 进行非顺序读取(随机读取)数据块的时候,会利用这个缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进行Join等等。总的来说,就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取,进而使用到 read_rnd_buffer_size 参数所设置的内存缓冲区。
net_buffer_size[thread]
连接信息及返回客户端前结果集暂存使用内存。这部分用来存放客户端连接线程的连接信息和返回客户端的结果集。当 MySQL 开始产生可以返回的结果集,会在通过网络返回给客户端请求线程之前,会先暂存在通过 net_buffer_size 所设置的缓冲区中,等满足一定大小的时候才开始向客户端发送,以提高网络传输效率。不过,net_buffer_size 参数所设置的仅仅只是该缓存区的初始化大小,MySQL 会根据实际需要自行申请更多的内存以满足需求,但最大不会超过 max_allowed_packet 参数大小。tmp_table_size[thread]
临时表使用内存。当我们进行一些特殊操作如需要使用临时表才能完成的 Order By,Group By 等等,MySQL 可能需要使用到临时表。当我们的临时表较小(小于 tmp_table_size 参数所设置的大小)的时候,MySQL 会将临时表创建成内存临时表,只有当 tmp_table_size 所设置的大小无法装下整个临时表的时候,MySQL 才会将该表创建成 MyISAM 存储引擎的表存放在磁盘上。不过,当另一个系统参数 max_heap_table_size 的大小还小于 tmp_table_size 的时候,MySQL 将使用 max_heap_table_size 参数所设置大小作为最大的内存临时表大小,而忽略 tmp_table_size 所设置的值。而且 tmp_table_size 参数从 MySQL 5.1.2 才开始有,之前一直使用 max_heap_table_size。