mysql性能低解决思路

mysql性能低解决思路:
一、mysql层面

1、查看慢查询日志(slow log)。
mysql性能低,大多是sql引起的,需要对慢sql进行优化
可以使用 pt-query-digest分析慢查询sql。

分析sql主要从:

利用explain 查看索引及扫描情况

利用set profiling=1,执行时间和等待时间两方面分析的sql的问题

[BEGIN] 
mysql> show variables like 'profi%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| profiling              | OFF   |
| profiling_history_size | 15    |
+------------------------+-------+
2 rows in set (0.00 sec)

mysql> set profiling=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SELECT COUNT(*) AS allnum
    -> , SUM(CASE 
    -> WHEN createtime < date_add(CURDATE(), INTERVAL 1 DAY)
    -> AND createtime > CURDATE()
    -> THEN 1
    -> ELSE 0
    -> END) AS todaynum
    -> , SUM(CASE 
    -> WHEN unappropriated = '0'
    -> AND `invalid_count` < 2
    -> THEN 1
    -> ELSE 0
    -> END) AS unappropriatednum
    -> , SUM(CASE 
    -> WHEN unappropriated = '1'
    -> AND currentservicerid = 'ISME9754_T2D_1'
    -> THEN 1
    -> ELSE 0
    -> END) AS currentservicernum
    -> , SUM(CASE 
    -> WHEN `finished` = 1 THEN 1
    -> ELSE 0
    -> END) AS finishednum
    -> , SUM(CASE 
    -> WHEN `invalid_count` >= 2 THEN 1
    -> ELSE 0
    -> END) AS invalidnum
    -> , SUM(CASE 
    -> WHEN `servicerid` = ''ISME9754_T2D_1' THEN 1
    -> ELSE 0
    -> END) AS serviceridnum
    -> FROM crm_user
    -> WHERE `siteid` = '9739'
    -> AND FIND_IN_SET(110268, gid);
+---------+----------+-------------------+--------------------+-------------+------------+---------------+
| allnum  | todaynum | unappropriatednum | currentservicernum | finishednum | invalidnum | serviceridnum |
+---------+----------+-------------------+--------------------+-------------+------------+---------------+
| 1434835 |     2487 |           1434800 |                  0 |           0 |          0 |          6616 |
+---------+----------+-------------------+--------------------+-------------+------------+---------------+
1 row in set (17.19 sec)

mysql> show profiles;
+----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Query_ID | Duration    | Query                                                                                                                                                                                                                                                                                                        |
+----------+-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
|        1 | 17.18347225 | SELECT COUNT(*) AS allnum SUM(CASE WHEN createtime < date_add(CURDATE(), INTERVAL 1 DAY)

+----------+-------------+----------------------------------------------------------------------------------------------------------------------------------------------
1 row in set, 1 warning (0.00 sec)

mysql> show profile for query 1;
+----------------------+-----------+
| Status               | Duration  |
+----------------------+-----------+
| starting             |  0.000211 |
| checking permissions |  0.000047 |
| Opening tables       |  0.000047 |
| init                 |  0.000098 |
| System lock          |  0.000042 |
| optimizing           |  0.000045 |
| statistics           |  0.000181 |
| preparing            |  0.000070 |
| executing            |  0.000042 |
| Sending data         | 17.182189 |
| end                  |  0.000121 |
| query end            |  0.000045 |
| closing tables       |  0.000046 |
| freeing items        |  0.000072 |
| logging slow query   |  0.000043 |
| Opening tables       |  0.000045 |
| System lock          |  0.000090 |
| cleaning up          |  0.000040 |
+----------------------+-----------+
18 rows in set, 1 warning (0.00 sec)

2、并发、锁、临时表等指标

tps、qps、并发连接数(Threads_connected)、并发活跃线程数(Threads_running)、临时表(tmp_disk_tables)、锁(locks_waited,innodb_row_rock*)等指标。

可以使用innotop工具可以清晰的查看相关情况

抓包分析:
tcpdump -s 65535 -x -nn -q -tttt -i any -c 10000 port 3306 >mysql.tcp.txt
pt-query-digest --type=tcpdump mysql.tcp.txt >mysql.tcp_repot.txt

利用mysqladmin查看
mysqladmin extended-status -r -i 1 | grep -E ‘Questions|Com_select|Com_update’

3、show processlist 查看当前线程状态:

如果出现以下状态可能不出现问题:

copy_tmp_table、creating_sort_index、Sorting_resoult、creating_tmp_table、长时间的sending data等

4、查看innodb_buffer_pool page的使用情况
主要是innodb_pages_free和innodb wait_free两个。

使用 pt-mysql-summary查看相关信息

5、多次执行show engine innodb status ,观察页面的变化情况:

Pages made young 1330334, not young 147073
0.00 youngs/s, 0.00 non-youngs/s

二、linux系统层面
1、使用top命令
内容输出:
link

查看load average表示当前的服务的平均负载,分为 1分钟、5分钟、15分钟。
us%是用户使用cpu占比,如果us%太高,极有可能索引使用不当。
sy%是系统内核使用的cpu占比,如果sy%太高,有可能是mysql的连接数和锁等信息。

wa%是I/O使用cpu的占比,如果wa%太高,有可能mysql使用了硬盘临时表,或者大量刷盘等操作,也有可能硬盘太慢、硬盘故障,可以使用iostat 、pt-diskstats等工具来采集信息。
pt-diskstats 磁盘性能监控利器,功能和iostat类似

# pt-diskstats

  #ts device    rd_s rd_avkb rd_mb_s rd_mrg rd_cnc   rd_rt    wr_s wr_avkb wr_mb_s wr_mrg wr_cnc   wr_rt busy in_prg    io_s  qtime stime
  0.6 vdc        1.6     4.0     0.0     0%    0.0     1.0    48.0     2.9     0.1     0%    0.0     0.8   4%      0    49.6    0.1   0.7
  0.6 vdc1       1.6     4.0     0.0     0%    0.0     1.0    48.0     2.9     0.1     0%    0.0     0.8   4%      0    49.6    0.1   0.7

  1.0 vdc        2.0     4.0     0.0     0%    0.0     1.0    37.0     5.2     0.2     0%    0.6    15.1  37%      2    39.0    5.1   9.4
  1.0 vdc1       2.0     4.0     0.0     0%    0.0     1.0    36.0     5.3     0.2     0%    0.6    15.6  37%      2    38.0    5.2   9.6

  1.0 vda        0.0     0.0     0.0     0%    0.0     0.0     2.0    44.0     0.1    91%    0.0     0.1   0%      0     2.0    0.0   0.1
  1.0 vda1       0.0     0.0     0.0     0%    0.0     0.0     2.0    44.0     0.1    91%    0.0     0.1   0%      0     2.0    0.0   0.1
  1.0 vdc        4.0     7.0     0.0     0%    0.0     1.0    68.0     7.8     0.5     0%    0.3     3.9  16%      0    72.0    1.2   2.2
  1.0 vdc1       4.0     7.0     0.0     0%    0.0     1.0    64.0     8.3     0.5     0%    0.3     4.2  16%      0    68.0    1.3   2.3

参数:

device:设备名称
rd_s:表示每秒读取次数
wr_s:表示每秒写入次数
rd_avkb:平均每次读请求的字节,单位KB/s,也是单次读取数据量。
rd_mb_s:该设备上的读取带宽,单位MB/s。rd_s*rd_avkb/1024=rd_mb_s。
rd_mrg:被合并的读取请求数占总的读取请求的百分比。越高越好
rd_cnc:读取请求并发。
rd_rt:读取请求平均响应时间。
wr_s、wr_avkb、wr_mb_s、wr_mrg、wr_cnc、wr_rt和读取请求类似。
busy:磁盘繁忙度。busy列,它与iostat中的util列相同,指向利用率
in_prg:
io_s:IOPS。rd_s+wr_s=ios_s
qtime:IO请求排队时间
stime:物理设备实际物理读写所耗费的时间,注意,服务时间(分别在pt-diskstats和iostat输出中的stime字段和svctm字段)在Linux上不可靠。如果您阅读了iostat 手册,您会看到它已被弃用。

查看某个指标:

# pt-diskstats --group-by sample --devices-regex sd[a] --columns-regex io_s
  #ts device    io_s
  0.5 {3}        0.0
  1.5 {3}        0.0
  2.5 {3}        0.0
  3.5 {3}        0.0
  4.5 {3}        0.0
  5.5 {3}        0.0
  6.5 {3}        0.0
  7.5 {3}        0.0
  8.5 {3}        0.0
  9.5 {3}        0.0

2、需要关注各个逻辑cpu之前的负载是否均衡(可能是不均衡导致性能问题),可以使用mpstat命令进行详细观察。
mpstat -P ALL 5

3、建议服务器为mysql专用。

4、是否使用了swap

5、内存使用率

free -m

6、是否发生内存泄漏
内存泄漏观察方法buff/cache和used对比。如果发生了内存泄漏解决方案:
1.重启mysql服务
2.将mysql升级到最新的小版本

7、通过vmstat来观察每秒的进程、内存、swap、I/O、cpu等详细情况。

8、iostat -x I/O使用情况

你可能感兴趣的:(MySQL)