Mysql数据库配置优化

1.tmp_table_size 临时表 (用于排序)

show global status like ‘created_tmp%’; 

| Variable_name | Value | 

| Created_tmp_disk_tables | 21197 | #在磁盘上创建临时表的次数 

| Created_tmp_files | 58 | #在磁盘上创建临时文件的次数

| Created_tmp_tables | 1771587 | #使用临时表的总次数

TmpTable的状况主要是用于监控MySQL使用临时表的量是否过多,

是否有临时表过大而不得不从内存中换出到磁盘文件上。 

a.如果:

Created_tmp_disk_tables/Created_tmp_tables>10%,则需调大tmp_table_size

比较理想的配置是:

Created_tmp_disk_tables/Created_tmp_tables<=25%

b.如果:

Created_tmp_tables非常大 ,则可能是系统中排序操作过多,或者是表连接方式不是很优化。

相关参数:

tmp_table_size 内存中,临时表区域总大小

max_heap_table_size 内存中,单个临时表的最大值,超过的部分会放到硬盘上。

 

2.连接数:

max_connections MySQL最大连接数

back_log 当连接数满了后,设置一个值,允许多少个连接进入等待堆栈

max_connect_errors 账号连接到服务器允许的错误次数

connect_timeout 一个连接报文的最大时间(单位:s)

skip-name-resolve 加入my.cnf即可,MySQL在收到连接请求的时候,会根据请求包 

中获得的ip来反向追查请求者的主机名。然后再根据返回

的主机名又一次去获取ip。如果两次获得的ip相同,那么连接就成功建立了。

加了次参数,即可省去这个步骤

NOTES:

查询当前连接数:show global status like 'connections';

 

4.table cache相关优化 :

参数table_open_cache,将表的文件描述符打开,cache在内存中

global status:

open_tables 当前系统中打开的文件描述符的数量

opened_tables 系统打开过的文件描述符的数量

 

5.慢查询日志:

slow_launch_time=2 查询大于某个时间的值(单位:s)

slow_query_log=on/off 开启关闭慢查询日志

slow_query_log_file=/opt/data/xxx.log 慢查询日志位置

 

6.查询缓存(Query Cache) 

将客户端的SQL语句(仅限select语句)通过hash计算,放在hash链表中,同时将该SQL的结果集

放在内存中cache。该hash链表中,存放了结果集的内存地址以及所涉及到的所有Table等信息。

如果与该结果集相关的任何一个表的相关信息发生变化后(包扩:数据、索引、表结构等),

就会导致结果集失效,释放与该结果集相关的所有资源,以便后面其他SQL能够使用。

当客户端有select SQL进入,先计算hash值,如果有相同的,就会直接将结果集返回。

Query Cache的负面影响:

a.使用了Query Cache后,每条select SQL都要进行hash计算,然后查找结果集。对于大量SQL

访问,会消耗过多额外的CPU。

b.如果表变更比较频繁,则会造成结果集失效率非常高。

c.结果集中保存的是整个结果,可能存在一条记录被多次cache的情况,这样会造成内存资源的

过度消耗。

Query Cache的正确使用:

a.根据表的变更情况来选择是否使用Query Cache,可使用SQL Hint:SQL_NO_CACHE和SQL_CACHE

b.对于 变更比较少 或 数据基本处于静态 的表,使用SQL_CACHE

c.对于结果集比较大的,使用Query Cache可能造成内存不足,或挤占内存。

可使用1.SQL_NO_CACHE 2.query_cache_limit控制Query Cache的最大结果集(系统默认1M)

mysql> show variables like '%query_cache%';

+------------------------------+---------+

| Variable_name | Value |

+------------------------------+---------+

| have_query_cache | YES | #是否支持Query Cache

| query_cache_limit | 1048576 | #单个结果集的最大值,默认1M

| query_cache_min_res_unit | 4096 | #每个结果集存放的最小内存,默认4K

| query_cache_size | 0 | #Query Cache总内存大小,必须是1024的整数倍

| query_cache_type | ON | #ON,OFF,DEMAND(包含SQL_CACHE的查询中才开启)

| query_cache_wlock_invalidate | OFF | 

+------------------------------+---------+

#query_cache_wlock_invalidate:

针对于MyISAM存储引擎,设置当有WRITELOCK在某个Table上面的时候,

读请求是要等待WRITE LOCK释放资源之后再查询还是允许直接从QueryCache中读取结果,

默认为FALSE(可以直接从QueryCache中取得结果)

 

mysql> show status like 'qcache%';

+-------------------------+-------+

| Variable_name | Value |

+-------------------------+-------+

| Qcache_free_blocks | 0 | 

| Qcache_free_memory | 0 |

| Qcache_hits | 0 |

| Qcache_inserts | 0 |

| Qcache_lowmem_prunes | 0 |

| Qcache_not_cached | 0 |

| Qcache_queries_in_cache | 0 |

| Qcache_total_blocks | 0 |

+-------------------------+-------+

# Qcache_free_blocks

QueryCache中目前还有多少剩余的blocks

a.如果Qcache_free_blocks值较大,说明Query Cache中内存碎片比较多

b.如果Qcache_free_blocks约等于Qcache_total_blocks/2,说明内存碎片非常严重

移除碎片:

flush query cache;

这个命令会把所有的存储块向上移动,并把自由块移到底部。

查询缓存碎片率:

查询缓存碎片率 = Qcache_free_blocks / Qcache_total_blocks * 100%

c.如果:

查询缓存碎片率超过20%, 可以用flush query cache整理碎片,或者减小

query_cache_min_res_unit(如果该系统的查询都是小数据量的话)

# Qcache_free_memory

QueryCache中目前剩余的内存大小

查询缓存利用率:

查询缓存利用率 = (query_cache_size – Qcache_free_memory) / query_cache_size * 100%

a.如果:

查询缓存利用率在25%以下,说明query_cache_size设置过大,可适当减小。

b.如果:

查询缓存利用率>80%,且Qcache_lowmem_prunes>50,说明query_cache_size可能有点小,或者

有太多的碎片

# Qcache_hits 

Query Cache的命中次数,可以看到QueryCache的基本效果;

# Qcache_inserts

Query Cache未命中然后插入的次数

Query Cache的命中率:

=Qcache_hits/(Qcache_hits+Qcache_inserts)

# Qcache_lowmem_prunes 

因为内存不足而被清除出Query Cache的SQL数量。

如果:

Qcache_lowmem_prunes的值正在增加,并且有大量的Qcache_free_blocks,

这意味着碎片导致查询正在被从缓存中永久删除。

# Qcache_not_cached

因为query_cache_type的设置或者不能被cache的select SQL数量

# Qcache_queries_in_cache

Query Cache中cache的select SQL数量

# Qcache_total_blocks

当前Query Cache中block的总数量

Query Cache限制:

a) 5.1.17之前的版本不能Cache帮定变量的Query,但是从5.1.17版本开始,QueryCache已经开

始支持帮定变量的Query了; 

b) 所有子查询中的外部查询SQL不能被Cache; 

c) 在Procedure,Function以及Trigger中的Query不能被Cache; 

d) 包含其他很多每次执行可能得到不一样结果的函数的Query不能被Cache。

 

7.进程的使用情况

在MySQL中,为了尽可能提高客户端请求创建连接这个过程的性能,实现了一个ThreadCache池,

将空闲的连接线程存放在其中,而不是完成请求后就销毁。这样,当有新的连接请求的时候,

MySQL首先会检查ThreadCache池中是否存在空闲连接线程,如果存在则取出来直接使用,

如果没有空闲连接线程,才创建新的连接线程。

参数:thread_cache_size

thread cache 池中存放的最大连接数

调整参考:

在短连接的数据库应用中,数据库连接的创建和销毁是非常频繁的,

如果每次都需要让MySQL新建和销毁相应的连接线程,那么这个资源消耗实际上是非常大的,因此

thread_cache_size的值应该设置的相对大一些,不应该小于应用系统对数据库的实际并发请求数。

参数:thread_stack - 每个连接线程被创建的时候,MySQL给他分配的内存大小,

类似PGA中存放数据的内存部分(不包括排序的空间)

show status like 'connections';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Connections | 80 | #接受到的来自客户端的总连接数,包括以前和现在的连接。

+---------------+-------+

show status like 'thread%';

+-------------------+-------+

| Variable_name | Value |

+-------------------+-------+

| Threads_cached | 0 | #当前系统中,缓存的连接数

| Threads_connected | 1 | #当前系统中正连接的线程数

| Threads_created | 77 | #创建过的总线程数

| Threads_running | 1 | 

+-------------------+-------+

a.如果:

Threads_created 值过大,说明MySQL一直在创建线程,这是比较消耗资源的,应该适当增大

thread_cache_size的值

b.如果:

Threads_cached的值比参数thread_cache_size小太多,则可以适当减小thread_cache_size的值

ThreadCache命中率:

Threads_Cache_Hit=(Connections-Threads_created)/Connections*100%

一般来说,当系统稳定运行一段时间之后,我们的ThreadCache命中率应该保持在90%

左右甚至更高的比率才算正常。

 

8.key_buffer_size 

索引缓存大小,是对MyISAM表性能影响最大的一个参数

32bit平台上,此值不要超过2GB,64bit平台不用做此限制,但也不要超过4GB

根据3点计算:

a.系统索引总大小 

b.系统物理内存 

c.系统当前keycache命中率

粗略计算公式:

Key_Size =key_number*(key_length+4)/0.67 

Max_key_buffer_size<Max_RAM-QCache_Usage-Threads_Usage-System_Usage 

Threads_Usage = max_connections * (sort_buffer_size + join_buffer_size + 

read_buffer_size+read_rnd_buffer_size+thread_stack)

key_cache_block_size ,是key_buffer缓存块的单位长度,以字节为单位,默认值为1024。

key_cache_division_limit 控制着缓存块重用算法。默认值为100,此值为key_buffer_size中暖链所占的大小百分比(其中有暖链和热链),100意味着全是暖链。(类似于Oracle Data Buffer Cache中的default、keep、recycle)

key_cache_age_threshold 如果key_buffer里的热链里的某个缓存块在这个变量所设定的时间里没有被访问过,MySQL服务器就会把它调整到暖链里去。这个参数值越大,缓存块在热链里停留的时间就越长。

这个参数默认值为 300,最小值为100。

Myisam索引默认是缓存在原始key_buffer中的,我们可以手动创建新的key_buffer,如在my.cnf中加入参数new_cache.key_buffer_size=20M。指定将table1和table2的索引缓存到new_cache的key_buffer中:

cache index table1,table2 in new_cache;

(之前默认的key_buffer为default,现在手动创建的为new_cache)

手动将table1和table2的索引载入到key_buffer中:

load index into cache table1,table2;

 

系统中记录的与Key Cache相关的性能状态参数变量: global status 

l Key_blocks_not_flushed,已经更改但还未刷新到磁盘的DirtyCacheBlock; 

l Key_blocks_unused,目前未被使用的CacheBlock数目; 

l Key_blocks_used,已经使用了的CacheBlock数目; 

l Key_read_requests,CacheBlock被请求读取的总次数; 

l Key_reads,在CacheBlock中找不到需要读取的Key信息后到“.MYI”文件中(磁盘)读取的次数; 

l Key_write_requests,CacheBlock被请求修改的总次数; 

l Key_writes,在CacheBlock中找不到需要修改的Key信息后到“.MYI”文件中读入再修改的次数;

索引命中缓存率:

key_buffer_read_hits=(1-Key_reads/Key_read_requests)*100% 

key_buffer_write_hits=(1-Key_writes/Key_write_requests)*100%

该命中率就代表了MyISAM类型表的索引的cache

 

9.排序使用情况:

参数 :sort_buffer_size - 单个thread能用来排序的内存空间大小,系统默认2M

mysql> show variables like 'sort%';

+------------------+---------+

| Variable_name | Value |

+------------------+---------+

| sort_buffer_size | 2097144 |

+------------------+---------+

mysql> show global status like 'sort%';

+-------------------+-------+

| Variable_name | Value |

+-------------------+-------+

| Sort_merge_passes | 0 |#在内存中无法完成排序,而在磁盘上创建临时文件的次数(两倍)

| Sort_range | 0 |#在范围内执行的排序的数量

| Sort_rows | 0 |#已经排序的行数

| Sort_scan | 0 |#通过扫描表完成的排序的数量

+-------------------+-------+

 

10.表锁情况

mysql> show global status like 'table%';

+-----------------------+-------+

| Variable_name | Value |

+-----------------------+-------+

| Table_locks_immediate | 96 | # 表示立即释放的表锁数

| Table_locks_waited | 0 | # 表示需要等待的表锁数

+-----------------------+-------+

如果 Table_locks_immediate / Table_locks_waited > 5000,最好采用InnoDB引擎。

因为InnoDB是行锁而MyISAM是表锁,对于高并发写入的应用InnoDB效果会好些。

 

11.表扫描情况

mysql> show global status like 'handler_read%';

+-----------------------+-------+

| Variable_name | Value |

+-----------------------+-------+

| Handler_read_first | 60 |

| Handler_read_key | 2442 |

| Handler_read_next | 286 |

| Handler_read_prev | 0 |

| Handler_read_rnd | 28 |

| Handler_read_rnd_next | 3191 |

+-----------------------+-------+

mysql> show global status like 'com_select';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Com_select | 23 |

+---------------+-------+

计算表扫描率: 

表扫描率 = Handler_read_rnd_next / Com_select 

如果:

表扫描率超过4000,说明进行了太多表扫描,很有可能索引没有建好,

增加read_buffer_size值会有一些好处,但最好不要超过8MB。

# Handler_read_first

此选项表明SQL是在做一个全索引扫描(注意是全部,而不是部分),所以说如果存在WHERE语句,

这个值是不会变的。如果这个值的数值很大,既是好事 也是坏事。

说它好是因为毕竟查询是在索引里完成的,而不是数据文件里,说它坏是因为大数据量时,

即便是索引文件,做一次完整的扫描也是很费时的。

# Handler_read_key

此选项数值如果很高,说明系统高效的使用了索引,一切运转良好

# Handler_read_next

此选项表明在进行索引扫描时,按照索引从数据文件里取数据的次数

# Handler_read_prev

此选项表明在进行索引扫描时,按照索引倒序从数据文件里取数据的次数,

一般就是ORDER BY ... DESC。

# Handler_read_rnd

简单的说,就是查询直接操作了数据文件,很多时候表现为没有使用索引或者文件排序

可能是有大量的全表扫描或连接时没恰当使用keys。

The number of requests to read a row based on a fixed position. This value is 

high if you are doing a lot of queries that require sorting of the result. You 

probably have a lot of queries that require MySQL to scan entire tables or you 

have joins that do not use keys properly.

# Handler_read_rnd_next 

此选项表明在进行数据文件扫描时,从数据文件里取数据的次数。(物理IO次数)

 

12.MySQL内存分配

mysql服务器为每个连接上的客户端线程,分配的内存空间:

read_buffer_size + read_rnd_buffer_size + sort_buffer_size + 

thread_stack + join_buffer_size

从内存的使用方式MySQL 数据库的内存使用主要分为以下两类

· 线程独享内存

· 全局共享内存

先分析 MySQL 中主要的 “线程独享内存” 的。

在 MySQL 中,线程独享内存主要用于各客户端连接线程存储各种操作的独享数据,如线程栈信息,分组排序操作,数据读写缓冲,结果集暂存等等,而且大多数可以通过相关参数来控制内存的使用量。

线程栈信息使用内存(thread_stack):

主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等,我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。

排序使用内存(sort_buffer_size):

MySQL 用此内存区域进行排序操作(filesort),完成客户端的排序请求。当我们设置的排序区缓存大小无法满足排序实际所需内存的时候,MySQL 会将数据写入磁盘文件来完成排序。由于磁盘和内存的读写性能完全不在一个数量级,所以sort_buffer_size参数对排序操作的性能影响绝对不可小视。排序操作的实现原理请参考:MySQL Order By 的实现分析(http://www.kuqin.com/database/20081206/29716.html)。

Join操作使用内存(join_buffer_size):

应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/index join),为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作(具体 Join 实现算法请参考:

MySQL 中的 Join 基本实现原理(http://www.kuqin.com/database/20081206/29717.html))。当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join 的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer 中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。

顺序读取数据缓冲区使用内存(read_buffer_size):

这部分内存主要用于当需要顺序读取数据的时候,如无法使用索引的情况下的全表扫描,全索引扫描等。在这种时候,MySQL 按照数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在read_buffer_size中,当 buffer 空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调用者,以提高效率。

随机读取数据缓冲区使用内存(read_rnd_buffer_size):

和顺序读取相对应,当 MySQL 进行非顺序读取(随机读取)数据块的时候,会利用这个缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进行Join等等。总的来说,就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取,进而使用到 read_rnd_buffer_size 参数所设置的内存缓冲区。

连接信息及返回客户端前结果集暂存使用内存(net_buffer_size):

这部分用来存放客户端连接线程的连接信息和返回客户端的结果集。当 MySQL 开始产生可以返回的结果集,会在通过网络返回给客户端请求线程之前,会先暂存在通过 net_buffer_size 所设置的缓冲区中,等满足一定大小的时候才开始向客户端发送,以提高网络传输效率。不过,net_buffer_size 参数所设置的仅仅只是该缓存区的初始化大小,MySQL 会根据实际需要自行申请更多的内存以满足需求,但最大不会超过 max_allowed_packet 参数大小。

批量插入暂存使用内存(bulk_insert_buffer_size):

当我们使用如 insert … values(…),(…),(…)… 的方式进行批量插入的时候,MySQL 会先将提交的数据放如一个缓存空间中,当该缓存空间被写满或者提交完所有数据之后,MySQL 才会一次性将该缓存空间中的数据写入数据库并清空缓存。此外,当我们进行 LOAD DATA INFILE 操作来将文本文件中的数据 Load 进数据库的时候,同样会使用到此缓冲区。

MySQL对硬件的"收益递减点“为256G内存,32CPU。

 

13.dalayed_queue_size

在被插入到实际的数据表里之前,来自insert delayed语句的数据航将在每个队列里等待

MySQL来处理他们。delayed_queue_size就是这个队列所能容纳的数据航的最大个数。当

这个队列满是,后续的insert delayed语句将被阻塞,直到这个队列里有容纳他们的空间

为止。

如果有很多客户在发出insert delayed语句以避免受阻塞,但你发现这些语句有阻塞的迹象,

加大这个变量的值将使更多的insert delayed语句更快地得到处理。

 

14.文件打开数 open_files_limit

mysql> show variables like 'open%';

+------------------+-------+

| Variable_name | Value |

+------------------+-------+

| open_files_limit | 1024 | #mysql总共能够打开的文件的数量

+------------------+-------+

mysql> show global status like 'open%file%';

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| Open_files | 79 | # 系统当前打开的文件数

| Opened_files | 278 | # 系统打开过的文件总数

+---------------+-------+

比较合适的设置:Open_files / open_files_limit * 100% <= 75%

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值