MySQL的性能指标计算和优化方法
MySQL的性能指标计算和优化方法
1 QPS计算(每秒查询数)
针对MyISAM引擎为主的DB
mysql> show global status like 'questions';
+---------------+------------+
| Variable_name | Value |
+---------------+------------+
| Questions | 2805815665 |
+---------------+------------+
1 row in set (0.00 sec)
mysql> show global status like 'uptime';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Uptime | 17115114 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> select 2805815665/17115114;
+---------------------+
| 2805815665/17115114 |
+---------------------+
| 163.9379 |
+---------------------+
1 row in set (0.00 sec)
QPS=questions/uptime=163,mysql自启动以来的平均QPS,如果要计算某一时间段内的QPS,可在高峰期间获取间隔时间t2-t1,然后分别计算出t2和t1时刻的q值,QPS=(q2-q1)/(t2-t1)
针对InnnoDB引擎为主的DB
mysql> show global status like 'com_update';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Com_update | 78299864 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> show global status like 'com_insert';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Com_insert | 80467605 |
+---------------+----------+
1 row in set (0.01 sec)
mysql> show global status like 'com_select';
+---------------+------------+
| Variable_name | Value |
+---------------+------------+
| Com_select | 3366989053 |
+---------------+------------+
1 row in set (0.00 sec)
mysql> show global status like 'com_delete';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Com_delete | 36038170 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> show global status like 'uptime';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Uptime | 17115204 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> select (78299864+80467605+36038170+3366989053)/78299864;
+--------------------------------------------------+
| (78299864+80467605+36038170+3366989053)/78299864 |
+--------------------------------------------------+
| 45.4892 |
+--------------------------------------------------+
1 row in set (0.00 sec)
QPS=(com_update+com_insert+com_delete+com_select)/uptime=45,某一时间段内的QPS查询方法同上。
2 TPS计算(每秒事务数)
mysql> show global status like 'com_commit';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Com_commit | 510648259 |
+---------------+-----------+
1 row in set (0.00 sec)
mysql> show global status like 'com_rollback';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Com_rollback | 95227537 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> show global status like 'uptime';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Uptime | 17115356 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> select (510648259+95227537)/17115356;
+-------------------------------+
| (510648259+95227537)/17115356 |
+-------------------------------+
| 35.3995 |
+-------------------------------+
1 row in set (0.00 sec)
TPS=(com_commit+com_rollback)/uptime=35
3 线程连接数和命中率
mysql> show global status like 'threads_%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_cached | 74 |//代表当前此时此刻线程缓存中有多少空闲线程
| Threads_connected | 106 |//代表当前已建立连接的数量,因为一个连接就需要一个线程,所以也可以看成当前被使用的线程数
| Threads_created | 16760 |//代表从最近一次服务启动,已创建线程的数量
| Threads_running | 6 |//代表当前激活的(非睡眠状态)线程数
+-------------------+-------+
4 rows in set (0.00 sec)
mysql> show global status like 'connections';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Connections | 18352277 |
+---------------+----------+
1 row in set (0.00 sec)
mysql> select 1-16760/18352277;
+------------------+
| 1-16760/18352277 |
+------------------+
| 0.9991 |
+------------------+
1 row in set (0.00 sec)
线程缓存命中率=1-Threads_created/Connections = 99.991%
设置线程缓存个数
mysql> show variables like '%thread_cache_size%';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| thread_cache_size | 128 |
+-------------------+-------+
1 row in set (0.00 sec)
根据Threads_connected可预估thread_cache_size值应该设置多大,一般来说250是一个不错的上限值,如果内存足够大,也可以设置成thread_cache_size值和threads_connected值相同;
或者通过观察threads_created值,如果该值很大或一直在增长,可以适当增加thread_cache_size的值;在休眠状态下每个线程大概占用256KB左右的内存,所以当内存足够时,设置太小也不会节约太多内存,除非该值已经超过几千。
4 表缓存
mysql> show global status like 'open_tables%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 1822 |
+---------------+-------+
1 row in set (0.00 sec)
设置打开表的缓存和表定义缓存
mysql> show variables like 'table_open_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| table_open_cache | 3000 |
+------------------+-------+
1 row in set (0.00 sec)
mysql> show variables like 'table_defi%';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| table_definition_cache | 1400 |
+------------------------+-------+
1 row in set (0.01 sec)
针对MyISAM:
mysql每打开一个表,都会读入一些数据到table_open_cache 缓存 中,当mysql在这个缓存中找不到相应的信息时,才会去磁盘上直接读取,所以该值要设置得足够大以避免需要重新打开和重新解析表的定义,一般设置为max_connections的10倍,但最好保持在10000以内。
还有种依据就是根据状态open_tables的值进行设置,如果发现open_tables的值每秒变化很大,那么可能需要增大table_open_cache的值。
table_definition_cache 通常简单设置为服务器中存在的表的数量,除非有上万张表。
针对InnoDB:
与MyISAM不同,InnoDB的open table和open file并无直接联系,即打开frm表时其相应的ibd文件可能处于关闭状态;
故InnoDB只会用到table_definiton_cache,不会使用table_open_cache;
其frm文件保存于table_definition_cache中,而idb则由innodb_open_files决定(前提是开启了innodb_file_per_table),最好将innodb_open_files设置得足够大,使得服务器可以保持所有的.ibd文件同时打开。
5 最大连接数
mysql> show global status like 'Max_used_connections';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| Max_used_connections | 1004 |
+----------------------+-------+
1 row in set (0.00 sec)
设置max_connections大小
mysql> show variables like 'max_connections%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 2000 |
+-----------------+-------+
1 row in set (0.00 sec)
通常max_connections的大小应该设置为比Max_used_connections状态值大,Max_used_connections状态值反映服务器连接在某个时间段是否有尖峰,如果该值大于max_connections值,代表客户端至少被拒绝了一次,可以简单地设置为符合以下条件:Max_used_connections/max_connections=0.8
6 Innodb 缓存命中率
mysql> show global status like 'innodb_buffer_pool_read%';
+---------------------------------------+---------------+
| Variable_name | Value |
+---------------------------------------+---------------+
| Innodb_buffer_pool_read_ahead_rnd | 0 |
| Innodb_buffer_pool_read_ahead | 730802 |//预读的页数
| Innodb_buffer_pool_read_ahead_evicted | 0 |
| Innodb_buffer_pool_read_requests | 3801141425753 |//从缓冲池中读取的次数
| Innodb_buffer_pool_reads | 2755728 |//表示从物理磁盘读取的页数
+---------------------------------------+---------------+
5 rows in set (0.00 sec)
mysql> select 3801141425753/(3801141425753+730802+2755728);
+----------------------------------------------+
| 3801141425753/(3801141425753+730802+2755728) |
+----------------------------------------------+
| 1.0000 |
+----------------------------------------------+
1 row in set (0.00 sec)
缓冲池命中率 = (Innodb_buffer_pool_read_requests)/(Innodb_buffer_pool_read_requests + Innodb_buffer_pool_read_ahead + Innodb_buffer_pool_reads)=100%
如果该值小于99.9%,建议就应该增大innodb_buffer_pool_size的值了,该值一般设置为内存总大小的75%-85%,或者计算出操作系统所需缓存+mysql每个连接所需的内存(例如排序缓冲和临时表)+MyISAM键缓存,剩下的内存都给innodb_buffer_pool_size,不过也不宜设置太大,会造成内存的频繁交换,预热和关闭时间长等问题。
7 MyISAM Key Buffer命中率和缓冲区使用率
mysql> show global status like 'key_%';
+------------------------+-------------+
| Variable_name | Value |
+------------------------+-------------+
| Key_blocks_not_flushed | 0 |
| Key_blocks_unused | 6692 |
| Key_blocks_used | 6698 |
| Key_read_requests | 51726731594 |
| Key_reads | 5423302 |
| Key_write_requests | 11733536354 |
| Key_writes | 77164219 |
+------------------------+-------------+
7 rows in set (0.00 sec)
mysql> show variables like '%key_cache_block_size%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| key_cache_block_size | 1024 |
+----------------------+-------+
1 row in set (0.00 sec)
mysql> show variables like '%key_buffer_size%';
+-----------------+---------+
| Variable_name | Value |
+-----------------+---------+
| key_buffer_size | 8388608 |
+-----------------+---------+
1 row in set (0.00 sec)
缓冲区的使用率=1-(Key_blocks_unused*key_cache_block_size/ key_buffer_size)=18.31%
读命中率=1-Key_reads /Key_read_requests=99.99%
写命中率=1-Key_writes / Key_write_requests =99.34%
可看到缓冲区的使用率并不高,如果很长一段时间后还没有使用完所有的键缓冲,可以考虑把缓冲区调小一点。
键缓存命中率可能意义不大,因为它和应用相关,有些应用在95%的命中率下就工作良好,有些则需要99.99%,所以从经验上看,每秒的缓存未命中次数更重要,假设一个独立磁盘每秒能做100个随机读,那么每秒有5个缓冲未命中可能不会导致I/O繁忙,但每秒80个就可能出现问题。
每秒缓存未命中=Key_reads/uptime=0.33
8 临时表使用情况
mysql> show global status like 'Created_tmp%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Created_tmp_disk_tables | 19226325 |
| Created_tmp_files | 117 |
| Created_tmp_tables | 56265812 |
+-------------------------+----------+
3 rows in set (0.00 sec)
mysql> show variables like '%tmp_table_size%';
+----------------+----------+
| Variable_name | Value |
+----------------+----------+
| tmp_table_size | 67108864 |
+----------------+----------+
1 row in set (0.00 sec)
可看到总共创建了56265812 张临时表,其中有19226325 张涉及到了磁盘IO,大概比例占到了0.34,证明数据库应用中排序,join语句涉及的数据量太大,需要优化SQL或者增大tmp_table_size的值,我设的是64M。该比值应该控制在0.2以内。
9 binlog cache使用情况
mysql> show status like 'Binlog_cache%';
+-----------------------+----------+
| Variable_name | Value |
+-----------------------+----------+
| Binlog_cache_disk_use | 645946 |
| Binlog_cache_use | 61175970 |
+-----------------------+----------+
2 rows in set (0.01 sec)
mysql> show variables like 'binlog_cache_size';
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| binlog_cache_size | 32768 |
+-------------------+-------+
1 row in set (0.00 sec)
Binlog_cache_disk_use表示因为我们binlog_cache_size设计的内存不足导致缓存二进制日志用到了临时文件的次数
Binlog_cache_use 表示 用binlog_cache_size缓存的次数
当对应的Binlog_cache_disk_use 值比较大的时候 我们可以考虑适当的调高 binlog_cache_size 对应的值
10 Innodb log buffer size的大小设置
mysql> show variables like '%innodb_log_buffer_size%';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| innodb_log_buffer_size | 8388608 |
+------------------------+---------+
1 row in set (0.00 sec)
mysql> show status like 'innodb_log_waits';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Innodb_log_waits | 0 |
+------------------+-------+
1 row in set (0.00 sec)
innodb_log_buffer_size设置为8M,应该足够大了;Innodb_log_waits表示因log buffer不足导致等待的次数,如果该值不为0,可以适当增大innodb_log_buffer_size的值。
11 表扫描情况判断
mysql> show global status like 'Handler_read%';
+-----------------------+---------------+
| Variable_name | Value |
+-----------------------+---------------+
| Handler_read_first | 121257954 |
| Handler_read_key | 79172593389 |
| Handler_read_last | 1192685 |
| Handler_read_next | 1397568482926 |
| Handler_read_prev | 48594574644 |
| Handler_read_rnd | 2584877785 |
| Handler_read_rnd_next | 1083694866736 |
+-----------------------+---------------+
7 rows in set (0.00 sec)
Handler_read_first:使用索引扫描的次数,该值大小说不清系统性能是好是坏
Handler_read_key:通过key进行查询的次数,该值越大证明系统性能越好
Handler_read_next:使用索引进行排序的次数
Handler_read_prev:此选项表明在进行索引扫描时,按照索引倒序从数据文件里取数据的次数,一般就是ORDER BY ... DESC
Handler_read_rnd:该值越大证明系统中有大量的没有使用索引进行排序的操作,或者join时没有使用到index
Handler_read_rnd_next:使用数据文件进行扫描的次数,该值越大证明有大量的全表扫描,或者合理地创建索引,没有很好地利用已经建立好的索引
12 Innodb_buffer_pool_wait_free
mysql> show global status like 'Innodb_buffer_pool_wait_free';
+------------------------------+-------+
| Variable_name | Value | |
+------------------------------+-------+
| Innodb_buffer_pool_wait_free | 0 |
+------------------------------+-------+
1 row in set (0.00 sec)
该值不为0表示buffer pool没有空闲的空间了,可能原因是innodb_buffer_pool_size设置太大,可以适当减少该值。
13 join操作信息
mysql> show global status like 'select_full_join';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Select_full_join | 10403 |
+------------------+-------+
1 row in set (0.00 sec)
该值表示在join操作中没有使用到索引的次数,值很大说明join语句写得很有问题
mysql> show global status like 'select_range';
+---------------+----------+
| Variable_name | Value |
+---------------+----------+
| Select_range | 22450380 |
+---------------+----------+
1 row in set (0.00 sec)
该值表示第一个表使用ranges的join数量,该值很大说明join写得没有问题,通常可查看select_full_join和select_range的比值来判断系统中join语句的性能情况
mysql> show global status like 'Select_range_check';
+--------------------+-------+
| Variable_name | Value |
+--------------------+-------+
| Select_range_check | 0 |
+--------------------+-------+
1 row in set (0.00 sec)
如果该值不为0需要检查表的索引是否合理,表示在表n+1中重新评估表n中的每一行的索引是否开销最小所做的联接数,意味着表n+1对该联接而言并没有有用的索引。
mysql> show GLOBAL status like 'select_scan';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| Select_scan | 116037811 |
+---------------+-----------+
1 row in set (0.00 sec)
select_scan表示扫描第一张表的连接数目,如果第一张表中每行都参与联接,这样的结果并没有问题;如果你并不想要返回所有行但又没有使用到索引来查找到所需要的行,那么计数很大就很糟糕了。
14 慢查询
mysql> show global status like 'Slow_queries';
+---------------+--------+
| Variable_name | Value |
+---------------+--------+
| Slow_queries | 114111 |
+---------------+--------+
1 row in set (0.00 sec)
该值表示mysql启动以来的慢查询个数,即执行时间超过long_query_time的次数,可根据Slow_queries/uptime的比值判断单位时间内的慢查询个数,进而判断系统的性能。
15表锁信息
mysql> show global status like 'table_lock%';
+-----------------------+------------+
| Variable_name | Value |
+-----------------------+------------+
| Table_locks_immediate | 1644917567 |
| Table_locks_waited | 53 |
+-----------------------+------------+
2 rows in set (0.00 sec)
这两个值的比值:Table_locks_waited /Table_locks_immediate 趋向于0,如果值比较大则表示系统的锁阻塞情况比较严重
MySQL的性能指标计算和优化方法的更多相关文章
- mysql索引的使用及优化方法
数据库高级管理及优化 MySQL性能优化 优化MySQL数据库是数据库管理员和数据库开发人员的必备技能.优化MySQL,一方面是找出系统的瓶颈,提高MySQL数据库整体的性能:另一方面是合理设计结构和 ...
- MySQL几点重要的性能指标计算和优化
qps 每秒处理的查询数tps 每秒处理的事务数IOPS 每秒磁盘进行的I/O操作次数 一.TPS:Transactions Per Second(每秒传输的事物处理个数),即服务器每秒处理的事务数. ...
- 30多条mysql数据库优化方法,千万级数据库记录查询轻松解决(转载)
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 30多条mysql数据库优化方法【转】
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- redmine在linux上的mysql性能优化方法与问题排查方案
iredmine的linux服务器mysql性能优化方法与问题排查方案 问题定位: 客户端工具: 1. 浏览器inspect-tool的network timing工具分析 2. 浏览 ...
- mysql数据库优化方法大数据量查询轻松解决
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- MySQL性能优化方法四:SQL优化
原文链接:http://isky000.com/database/mysql-performance-tuning-sql 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需 ...
- 转载:30多条mysql数据库优化方法,千万级数据库记录查询轻松解决
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- 最全 MySQL 优化方法,从此优化不再难
说起MySQL的查询优化,相信大家收藏了一堆奇技淫巧:不能使用SELECT *.不使用NULL字段.合理创建索引.为字段选择合适的数据类型..... 你是否真的理解这些优化技巧?是否理解其背后的工作原 ...
随机推荐
- mysql学习记录(一)
#打开MySQL服务 sudo service mysql start #Ubuntu Linux 安装配置MySQL #安装MySQL服务器,核心程序 sudo apt-get install my ...
- 分布式事务中的2PC和3PC
分布式事务 分布式事务是指会涉及到操作多个数据库的事务.其实就是将对同一库事务的概念扩大到了对多个库的事务. 分布式事务中需要注意的是分布式系统中存在的一致性问题: CAP原则:在一个分布式系统中,C ...
- java 技术分享
http://www.ccblog.cn/99.htm http://www.ccblog.cn/100.htm http://www.ccblog.cn/101.htm http://www.ccb ...
- 使用nginx配置二级域名
使用nginx配置二级域名 2018.11.21 11:51:17字数 613阅读 170 最近想把三个项目配在一个服务器上,于是想使用nginx配置二级域名实现. 1.域名添加解析 我的是阿里云的域 ...
- hdlg WM_INITDIALOG
https://www.cnblogs.com/gakusei/articles/1585212.html // “关于”框的消息处理程序. LRESULT CALLBACK About(HWND h ...
- ascii 八进制
int main() 4 { 5 char buf[20] = {'\101','\102','\103',0}; 6 printf("%s",buf); 7 return 0; ...
- Ubuntu 16.04 安装摄像头驱动usb_cam
!!需要在ROS平台上安装 ROS见 https://www.cnblogs.com/haijian/p/8782560.html cd ~/catkin_ws/src 下载usb_cam包 gi ...
- SpringBoot实体类对象和json格式的转化
1.引入maven依赖 <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson ...
- js原生高逼格插件
如何定义一个高逼格的原生JS插件 作为一个前端er,如果不会写一个小插件,都不好意思说自己是混前端界的.写还不能依赖jquery之类的工具库,否则装得不够高端.那么,如何才能装起来让自己看起来逼格更高 ...
- unittest----常用属性详解(框架属性详解)
很久没有写关于测试的随笔了,最近有空学习.整理一下关于unittest框架的知识. unittest单元测试框架,不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行. unittest ...