当前位置:首页 > 问答 > 正文

看了MySQL的status信息,试着找点优化服务器性能的小门道

看了MySQL的status信息,试着找点优化服务器性能的小门道,这些东西就像汽车仪表盘,虽然看不懂所有指示灯,但抓住几个关键的,就能知道车子是不是“有病”。

别一上来就想着调各种复杂的参数,最实在的第一步,是去看看MySQL现在正在“忙活”些什么,可以用SHOW PROCESSLIST;这个命令(来源:MySQL官方手册),这个命令一执行,你会看到一列当前数据库的连接和它们正在执行的SQL语句,你要找的就是那种“执行时间”(Time列)特别长的家伙,如果一个查询卡在那里几十秒甚至几分钟,那它八成就是个“问题查询”,它可能不仅自己慢,还会堵住后面的查询,就像高速上一个开得极慢的车堵了一路,把这些“慢车”找出来,要么优化它的写法(比如加个索引),要么看看是不是没必要实时跑,可以放到业务不忙的时候去处理。

我们看看几个关键的status指标,用SHOW GLOBAL STATUS LIKE '%这里写关键词%';来查看。

第一个要盯住的是Threads_connectedThreads_running(来源:MySQL官方手册对Status Variables的描述)。Threads_connected是说现在有多少个客户端连到了数据库上,这个数字如果平时一直很高,可能意味着你的程序没有及时关闭数据库连接,就像好多人占着电话线但不说话,更关键的是Threads_running,它表示此刻真正在“干活”(执行查询)的线程数,如果这个数持续很高,比如一直超过CPU的核数,说明服务器已经非常繁忙,快忙不过来了,这时候用户就会明显感觉到卡顿,这时候你可能需要检查是不是有大量复杂查询同时涌进来,或者考虑给数据库服务器升级硬件了。

第二个要看的是Innodb_buffer_pool_readsInnodb_buffer_pool_read_requests(来源:Percona等性能优化专家的常见实践),这俩指标是衡量数据库“记忆力”好不好的,MySQL会把经常用到的数据放在一块叫Buffer Pool的内存里,这样下次再要读的时候,直接从内存拿就飞快。read_requests是总共的读请求次数,reads是其中不得不从硬盘里读取的次数,硬盘比内存慢成千上万倍,计算一下硬盘读的比例:Innodb_buffer_pool_reads / Innodb_buffer_pool_read_requests,如果这个比值很高,比如超过1%甚至更高,那就说明你的Buffer Pool大小可能不够用,数据库老是记不住东西,要频繁去翻硬盘这本“慢速词典”,这时候,适当增大innodb_buffer_pool_size这个参数,让数据库有更多内存来缓存数据,性能提升会非常明显。

第三个有用的指标是Slow_queries(来源:MySQL官方手册),这个计数器会记录执行时间超过long_query_time(默认是10秒)的查询数量,你可以定期看看这个数字的增长速度,如果它蹭蹭地往上涨,毫无疑问,你的系统里出现了很多慢查询,这时候你就需要去开启MySQL的慢查询日志(设置slow_query_log=ON),把那些具体的慢查询语句抓出来,一个个分析优化,这是性价比最高的优化手段之一。

第四个,看看Aborted_connectsAborted_clients(来源:MySQL官方手册对Status Variables的描述),这两个指标反映了连接是否健康。Aborted_connects是说尝试连接但失败的次数,比如密码输错了,如果这个数高,要检查一下是不是有程序在配错了密码还不停地尝试。Aborted_clients是说客户端没有正常关闭连接就退出了(比如网络断了或者程序崩溃),如果这个数异常的高,可能意味着网络不稳定,或者应用程序没有做好异常处理,虽然不直接拖慢查询速度,但频繁的非正常连接中断也会给服务器带来不必要的负担。

提一下Select_scanHandler_read_first(来源:基于索引原理的通用性能分析)。Select_scan表示执行了全表扫描的查询数量,全表扫描就是数据库为了找一条数据,不得不把整张表的数据都翻一遍,效率极低,而Handler_read_first等指标可以反映索引的使用情况,理想情况下,大部分查询都应该通过索引来快速定位数据,如果发现Select_scan的值增长很快,那就要去检查相关的表是不是缺少合适的索引,给经常作为查询条件的字段加上索引,就像给书加上目录,能让查询速度发生质变。

看Status信息,不要追求面面俱到,就抓住几个点:有没有慢查询(Slow_queries, PROCESSLIST)、内存够不够用(Buffer Pool相关指标)、连接压力大不大(Threads_running)、有没有全表扫描(Select_scan),从这些地方入手,顺藤摸瓜,往往就能找到服务器性能瓶颈的蛛丝马迹,然后进行有针对性的优化,效果会立竿见影。

看了MySQL的status信息,试着找点优化服务器性能的小门道