1.死锁
1.查看死锁,一般来说使用 show processlist
2.重点关注state和info列
3.重点状态 locked,如果是长时间locked 则有可能锁住
4.Copying to tmp table: 由于临时结果集大于tmp_table_size,正在将临时表从内存存储转为磁盘存储以此节省内存。IO和CPU可能会飙升,表示数据量和查询相当多和复杂.索引等问题。
5.Waiting for net ,reading from net,writing to net:长时间出现,一般是网络数据量大,检查网卡。或者把数据流量压缩,大数据拆小给应用处理
2.SQL优化
主要通过索引,慢查询-mysqldumpslow-explain执行计划,查看分析慢SQL
主要解决方案
建立合适的索引
SQL语句结构调整
大SQL语句拆分,由应用程序分担压力
调整参数
重点关注
type
表示MySQL在表中找到所需行的方式,又称“访问类型”
all、index、range、ref、eq_ref、const,system、null
key
显示MySQL在查询中实际使用的索引,若没有使用索引,显示为NULL
rows
表示mysql根据表统计信息以及索引选用情况,估算找到所需记录需要读取的行数
extra
• 如果是Only index,这意味着信息只用索引就找到了
• 如果是where used,就是使用上了where限制。
• 如果是impossible where 表示用不着where,一般就是没查出来啥。
• 如果此信息显示Using filesort或者Using temporary的话会很吃力,WHERE和ORDER BY的索引经常无法兼顾,如果按照WHERE来确定索引,那么在ORDER BY时,就必然会引起Using filesort,这就要看是先过滤再排序划算,还是先排序再过滤划算。
• 这里我们只需要关心是否存在using filesort或using temporary即可。
主要分析
using filesort
1.排序时无法使用到索引时,就会出现这个。常见于order by和group by语句中
2.所以主要考虑优化索引和sql结构解决
using temporary
1.为了解决查询,MySQL需要创建一个临时表来容纳结果。典型情况如查询包含可以按不同情况列出列的GROUP BY和ORDER BY子句时
2.如果说进行filesort时,sort buffer不足,则会调用temporary来处理
3.所以主要考虑修改索引buffer和排序buffer 查询cache ,减少查询字段等方式解决
则有如下优化方向:
1. 加大 max_length_for_sort_data 参数的设置
2. 去掉不必要的返回字段
3. 增大 sort_buffer_size 参数设置(session变量,建议不要超过4M)
4.设置较大的key_buffer_size和query_cache_size的值(全局参数)
using filesort和using temporary同时出现时:
1.一般先优化using filesort
2.当using filesort无法避免时,调整参数优化using temporary
当type为all或者rows字段很大时:
1.type为all说明没有走索引,有明显的优化余地
2.rows很大,或者rows值和实际查询结果值查询较大,说明查询了很多不必要的数据
3.通常通过优化sql语句 或者索引来完成
using index条件:
说明:即使用索引对数据进行排序,不需要进行回表。取出满足过滤条件作为排序条件的字段,以及可以直接定位到行数据的行指针信息,在 Sort Buffer 中进行实际的排序操作,然后利用排好序的数据根据行指针信息返回表中取得客户端请求的其他字段的数据,再返回给客户端.
1.select 返回选择的字段 包含在索引中
2.只有当ORDER BY中所有的列必须包含在相同的索引,并且索引的顺序和order by子句中的顺序完全一致,并且所有列的排序方向(升序或者降序)一样才有,(混合使用ASC模式和DESC模式则不使用索引)
3.where 语句与ORDER BY语句组合满足最左前缀
4.如果查询联接了多个表,只有在order by子句的所有列引用的是第一个表的列(驱动表)才可以
using filesort情况:
说明:无法使用索引进行排序,需要回表取出所有数据在sort buffer中进行排序。MySQL需要将数据在内存中进行排序,所使用的内存区域也就是我们通过sort_buffer_size 系统变量所设置的排序区。这个排序区是每个Thread 独享的,所以说可能在同一时刻在MySQL 中可能存在多个 sort buffer 内存区域
1) where语句与order by语句,使用了不同的索引
2) 检查的行数过多,且没有使用覆盖索引
3) ORDER BY中的列不包含在相同的索引,也就是使用了不同的索引
4) 对索引列同时使用了ASC和DESC
5) where语句或者ORDER BY语句中索引列使用了表达式,包括函数表达式
6) where 语句与ORDER BY语句组合满足最左前缀,但where语句中使用了条件查询。虽然where与order by构成了索引最左有缀的条件,但是where子句中使用的是条件查询。
7) 当使用left join,使用右边的表字段排序
3.参数优化
增大连接数:
1.Max_used_connections / max_connections 值在85%左右
2.max_connections一般设置500-1000
3.典型报错MySQL: ERROR 1040: Too many connections
调整超时时间:
wait_timeout
interactive_timeout
默认28800秒 8小时,2个参数需要一起改
典型报错
现象:当应用程序和数据库建立连接时,如果超过了8个小时,应用程序不去访问数据库,数据库就会出现断掉连接的现象 。这时再次访问就会抛出异常
调整日志级别:
innodb_flush_log_at_trx_commit
表示日志记录级别
0 log thread 每隔1秒钟会将log buffer中的数据写入到文件,还通知文件系统进行同步flush操作,保证文件写入物理文件
1 每次事务结束,log thread都会写入,并通知文件系统flush
2 每次事务结束,log thread都会写入到文件系统,但这只是调用了操作系统的文件写入,没有调用flush操作,文件系统什么时候flush写入磁盘文件,不由log thread控制
所以,1安全性最好,2其次,0最低。性能正好相反,安全性越高越是牺牲性能
innodb_log_buffer_size
为尚未执行的事务(等待中)提供的缓存
默认值1MB,单位MB
判断 show variables like 'innodb_log_waits' 如果不是0,则考虑增加innodb_log_buffer_size
调整各类缓冲缓存大小:
加大buffer缓冲池大小 innodb_buffer_pool_size
show variables like 'innodb_buffer_pool_size';
缓冲池是存放数据和索引的地方,加大这个值,减少IO操作,使数据操作是在内存中而不是硬盘
典型的值是5-6GB(8GB内存),20-25GB(32GB内存),100-120GB(128GB内存)。
注意单位是MB
增大索引缓存区大小 key_buffer_size
MyISAM表中的索引缓存
show variables like 'key_buffer_size';
查看key_buffer_size参数设置的大小,单位B
计算索引未命中缓存的概率:
• key_cache_miss_rate = Key_reads / Key_read_requests * 100%
• 需要的值可以从该语句获取:show global status like 'key_read%';
• key_cache_miss_rate在0.1%以下都很好。如果key_cache_miss_rate在0.01%以下的话,而key_buffer_size分配的过多,可以适当减少。
调整事务等待缓存 innodb_log_buffer_size
为尚未执行的事务(等待中)提供的缓存
默认值1MB,单位MB
判断 show variables like 'innodb_log_waits' 如果不是0,则考虑增加innodb_log_buffer_size
设置最大查询长度 加大 max_length_for_sort_data 参数的设置
增加查询缓存区大小 增大 sort_buffer_size 参数设置
增加查询cache大小 query_cache_size
减少SQL中using temporary
1. 加大 max_length_for_sort_data 参数的设置
2. 去掉不必要的返回字段
3. 增大 sort_buffer_size 参数设置(session变量,建议不要超过4M)
4.设置较大的key_buffer_size和query_cache_size的值(全局参数)
4.存储引擎优化
如果使用MyISAM的数据库,造成大量死锁 慢查询,尽量改用innodb数据库
看你的mysql现在已提供什么存储引擎:
mysql> show engines;
看你的mysql当前默认的存储引擎:
mysql> show variables like '%storage_engine%';
你要看某个表用了什么引擎(在显示结果里参数engine后面的就表示该表当前用的存储引擎):
mysql> show create table 表名;