Linux性能优化实战学习笔记:第二十八讲

Linux性能优化实战学习笔记:第二十八讲

一、案例环境描述

1、环境准备

2CPU,4GB内存

预先安装docker sysstat工具

?

1

apt install docker.io sysstat nake git

案例总共由三个容器组成:

1、包括一个 MySQL 数据库应用、
2、一个商品搜索应用
3、一个数据处理的应用。

其中,商品搜索应用以 HTTP 的形式提供了一个接口:

/:返回 Index Page;
/db/insert/products/:插入指定数量的商品信息
/products/:查询指定商品的信息,并返回处理时间。

2、架构图

今天的案例需要两台虚拟机,其中一台作为案例分析的目标机器,运行 Flask 应用,它的 IP 地址是 192.168.0.10;另一台则是作为客户端,请求单词的热度。我画了一张图表示它们的关系。

3、测试环境准备

首先、我们在第一个终端中执行下面命令,拉去本次案例所需的脚本:

?

1

2

git clone https://github.com/feiskyer/linux-perf-examples

$ cd linux-perf-examples/mysql-slow

接着,执行下面的命令,运行本次的目录应用,正常情况下,你应该可以看到下面的输出

?

1

2

3

4

5

6

7

[root@luoahong mysql-slow]# make run

docker run --name=mysql -itd -p 10000:80 -m 800m feisky/mysql:5.6

eb934a265f31aaedc262c89c9dcd201c4b77f704b65119dc683b63726f578a3e

docker run --name=dataservice -itd --privileged feisky/mysql-dataservice

d7183422cf1213ccc1797a1f5a79fc8f14a997ef3942cf999dab8c2c72dc8b2b

docker run --name=app --network=container:mysql -itd feisky/mysql-slow

f08ca0395fccbd187a57eba932cd072c8460b1a9decff0e1cde46472c8eb409d

注意容器下面的碎字符串是容器ID,每次运行均会不同,并且你不需要关注它,因为我们只会用到名字  

然后,再次运行docker ps命令,确认三个容器都处在运行(Up)状态;

?

1

2

3

4

5

6

[root@luoahong mysql-slow]# docker ps

CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS              PORTS                             NAMES

f08ca0395fcc        feisky/mysql-slow          "python /app.py"         27 seconds ago      Up 26 seconds                                         app

d7183422cf12        feisky/mysql-dataservice   "python /dataservice…"   28 seconds ago      Up 26 seconds                                         dataservice

eb934a265f31        feisky/mysql:5.6           "docker-entrypoint.s…"   29 seconds ago      Up 27 seconds       3306/tcp, 0.0.0.0:10000->80/tcp   mysql

[root@luoahong mysql-slow]#

MySQL数据库的启动过程,需要做一些初始化工作,这通常需要花费几分钟时间,你可以运行dockers log命令、查看它的启动过程

?

1

2

3

4

5

6

7

8

9

10

11

[root@luoahong mysql-slow]# docker logs -f mysql

Initializing database

2019-05-30 06:27:03 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).

2019-05-30 06:27:03 0 [Note] Ignoring --secure-file-priv value as server is running with --bootstrap.

2019-05-30 06:27:25 1 [Note] Server socket created on IP: '::'.

......

2019-05-30 06:27:25 1 [Warning] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.

2019-05-30 06:27:25 1 [Warning] 'proxies_priv' entry '@ root@eb934a265f31' ignored in --skip-name-resolve mode.

2019-05-30 06:27:25 1 [Note] Event Scheduler: Loaded 0 events

2019-05-30 06:27:25 1 [Note] mysqld: ready for connections.

Version: '5.6.42-log'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)

确认商品搜索应用在10000端口监听,确认它也已经正常运行

?

1

2

[root@luoahong tools]# curl http://127.0.0.1:10000/

Index Page[root@luoahong tools]#

二、故障现象

1、发现故障

运行make init命令,初始化数据库、插入10000条商品信息(这个过程比较慢,大约需要十几分钟的时

?

1

2

3

4

[root@luoahong mysql-slow]# make init

docker exec -i mysql mysql -uroot -P3306 < tables.sql

curl http://127.0.0.1:10000/db/insert/products/20000

insert 20000 lines

在第二个终端,访问一下商品搜索的接口、看看能不能找到想要的商品、执行如下的curl命令

?

1

2

[root@luoahong mysql-slow]# curl http://192.168.118.115:10000/products/geektime

Got data: () in 8.804400205612183 sec

2、故障现象

稍等一会儿,你会发现,这个接口返回的是空数据,而且处理时间超过15秒,这么慢的响应速度让人无法忍受,到底出了什么问题呢?

三、分析过程

在第二个终端继续执行下面的命令

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[root@luoahong ~]# while true; do curl http://192.168.118.115:10000/products/geektime; sleep 5; done

Got data: () in 8.62768268585205 sec

Got data: () in 9.515994548797607 sec

Got data: () in 8.497008562088013 sec

Got data: () in 8.946581602096558 sec

Got data: () in 8.66761040687561 sec

Got data: () in 9.343888998031616 sec

Got data: () in 8.72763991355896 sec

Got data: () in 8.446544647216797 sec

Got data: () in 8.668050289154053 sec

Got data: () in 9.259597539901733 sec

Got data: () in 8.74580430984497 sec

Got data: () in 8.766760110855103 sec

Got data: () in 8.431026220321655 sec

1、首先、我们在中断执行top命令、分析系统的CPU使用情况:

观察top的输出,我们发现:

1、两个CPU的iowat都比较高、特别是cpu0,iowat已经超过了60%

2、而具体到各个进程, CPU 使用率并不高,最高的也只有17.2 

2、既然CPU嫌疑不大,那问题应该在I/O上,停止top命令;然后执行iostat命令,看看有没有I/O性能问题

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

[root@luoahong mysql-slow]# iostat -d -x 1

Linux 5.1.0-1.el7.elrepo.x86_64 (luoahong)  05/30/2019  _x86_64_    (2 CPU)

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda             16.27  10181.73     0.02   0.10   39.60   625.71   18.35    976.48     0.46   2.44    3.22    53.23    0.00      0.00     0

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda             30.00   4436.00     0.00   0.00    7.23   147.87    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.20   3.50

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            129.00 110716.00     1.00   0.77   46.16   858.26    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    5.89  19.10

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            118.00 112244.00     1.00   0.84   50.22   951.22    1.00      4.00     0.00   0.00   34.00     4.00    0.00      0.00     0.00   0.00    0.00     0.00    5.90  18.70

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            116.00 118784.00     0.00   0.00   54.59  1024.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.27  18.50

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            119.00 121600.00     0.00   0.00   53.70  1021.85    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.34  19.20

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            126.00 118788.00     2.00   1.56   54.24   942.76    1.00      4.00     0.00   0.00   40.00     4.00    0.00      0.00     0.00   0.00    0.00     0.00    6.81  19.20

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            106.00 109056.00     0.00   0.00   62.00  1028.83    1.00      7.50     0.00   0.00   52.00     7.50    0.00      0.00     0.00   0.00    0.00     0.00    6.50  16.50

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            101.00 102656.00     0.00   0.00   63.90  1016.40    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    6.47  16.10

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            127.72 120146.53     1.98   1.53   53.74   940.68    1.98     11.88     0.00   0.00   42.50     6.00    0.00      0.00     0.00   0.00    0.00     0.00    6.89  19.50

 

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util

sda            102.00  93000.00     0.00   0.00   48.75   911.76    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    4.92  14.50

1、磁盘 sda 每秒的读数据为 32 MB
2、而 I/O 使用率高达 97%
3、接近饱和,这说明,磁盘 sda 的读取确实碰到了性能瓶颈

3、如何知道这些进程是那些进程导致的呢?

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@luoahong mysql-slow]# pidstat -d 1

Linux 5.1.0-1.el7.elrepo.x86_64 (luoahong)  05/30/2019  _x86_64_    (2 CPU)

 

04:18:28 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

 

04:18:29 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

04:18:30 PM     0     10641      4.00      4.00      0.00       0  python

04:18:30 PM     0     10945      0.00      0.00      0.00       1  kworker/0:0-events

 

04:18:30 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

 

04:18:31 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

04:18:32 PM     0     10945      0.00      0.00      0.00       1  kworker/0:0-events_power_efficient

 

04:18:32 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command

04:18:33 PM     0     10263    556.00      0.00      0.00       0  bash

04:18:33 PM   999     10560  15872.00      0.00      0.00       0  mysqld

04:18:33 PM     0     10641      0.00      4.00      0.00       0  python

04:18:33 PM     0     11084   5792.00      0.00      0.00      29  curl

4、分析进程的数据读取 需要用到strace+ lsof 组合。

为什么mysqld会读取大量的磁盘数据呢?按照前面猜测,我们提到过、这有可能是慢查询问题
可是、回想一下、慢查询的现象大多是cpu使用率高,但这里的看到的确实I/O问题,看来、这并不是一个单纯的
慢查询问题,我们有必要分析一下mysql读取的数据

我们知道,MySQL 是一个多线程的数据库应用,为了不漏掉这些线程的数据读取情况,你要记得在执行stace 命令时,加上 -f 参数:

?

1

2

3

4

5

6

7

8

9

10

strace -f -p 10560

[pid 10919] read(37, "gOvH0QGqpShDOt3TFpB7mWFxIsGFpxEQ"..., 131072) = 131072

[pid 10919] read(37, "veWjWoElqB6E26n7ghhjHtFdRfUcQ4Vt"..., 20480) = 20480

[pid 10919] read(37, "tiyHTvaaW6XOT9Sq7dZMmNimVOPvFoWp"..., 131072) = 131072

[pid 10919] read(37, "78fMhVd5SH38edDFgwuLpDNdiNIp7mHo"..., 24576) = 24576

[pid 10919] read(37, "GpjARraEFkUJCzaO41iaoiVmWW730hS1"..., 131072) = 131072

[pid 10919] read(37, "T4K9rAkBz3cApPxKNJyPpSU6lK4CuUaq"..., 20480) = 20480

[pid 10919] read(37, "dUndUh2lEwhYK6ueXqfZ6jjj1Y9OSniP"..., 131072) = 131072

[pid 10919] read(37, "r7WsV96IojCmciSHlgk0Pp7oqkoq7hL4"..., 24576) = 24576

[pid 10919] read(37, "4kvN7g1EidOep0AFEN0bzOLNYjFt3FM0"..., 131072) = 131072

线程 10919 正在读取大量数据、且读取文件的描述符编号为 37。

5、这儿的 37 又对应着哪个文件呢?

?

1

2

3

[root@luoahong ~]# lsof -p 10919

[root@luoahong ~]# echo $?

1

为什么 lsof 命令执行失败了呢?

遇到现象解释不了,先去查查工具文档。事实上,通过查询 lsof 的文档,你会发现,-p 参数需要指定进程号,而我们刚才传入的是线程号,所以 lsof 失败了

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

[root@luoahong ~]# pstree -a -p 10560

mysqld,10560 --log_bin=on --sync_binlog=1

  ├─{mysqld},10856

  ├─{mysqld},10857

  ├─{mysqld},10858

  ├─{mysqld},10859

  ├─{mysqld},10860

  ├─{mysqld},10861

  ├─{mysqld},10862

  ├─{mysqld},10863

  ├─{mysqld},10864

  ├─{mysqld},10865

  ├─{mysqld},10867

  ├─{mysqld},10868

  ├─{mysqld},10869

  ├─{mysqld},10870

  ├─{mysqld},10871

  ├─{mysqld},10872

  ├─{mysqld},10873

  ├─{mysqld},10874

  ├─{mysqld},10875

  ├─{mysqld},10876

  └─{mysqld},10919

你会发现,mysqld 其实还有很多正在运行的其他线程:  

 6、找到了原因,lsof 的问题就容易解决了。把线程号换成进程号、继续执行 lsof 命令:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

[root@luoahong ~]# lsof -p 10560

COMMAND   PID    USER   FD   TYPE DEVICE   SIZE/OFF     NODE NAME

mysqld  10560 polkitd  cwd    DIR    8,2        239   455186 /var/lib/mysql

mysqld  10560 polkitd  rtd    DIR   0,42         28  1315612 /

mysqld  10560 polkitd  txt    REG   0,42   15759280 39165788 /usr/sbin/mysqld

......

mysqld  10560 polkitd  DEL    REG   0,17               65017 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65016 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65015 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65014 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65013 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65012 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65011 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65010 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65009 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65008 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65007 /[aio]

mysqld  10560 polkitd  DEL    REG   0,17               65004 /[aio]

mysqld  10560 polkitd    0u   CHR  136,0        0t0        3 /dev/pts/0

mysqld  10560 polkitd    1u   CHR  136,0        0t0        3 /dev/pts/0

mysqld  10560 polkitd    2u   CHR  136,0        0t0        3 /dev/pts/0

mysqld  10560 polkitd    3u   REG    8,2         48 21165914 /var/lib/mysql/on.index

mysqld  10560 polkitd    4uW  REG    8,2   12582912 18611645 /var/lib/mysql/ibdata1

mysqld  10560 polkitd    5u   REG   0,42          0 74328016 /tmp/ibbSKXmR (deleted)

mysqld  10560 polkitd    6u   REG   0,42          0 74328017 /tmp/ibeUxi1R (deleted)

mysqld  10560 polkitd    7u   REG   0,42          0 74328018 /tmp/ibaQWDFS (deleted)

mysqld  10560 polkitd    8u   REG   0,42          0 74328019 /tmp/iboRiwZT (deleted)

mysqld  10560 polkitd    9uW  REG    8,2   50331648 18611646 /var/lib/mysql/ib_logfile0

mysqld  10560 polkitd   10uW  REG    8,2   50331648 18611647 /var/lib/mysql/ib_logfile1

mysqld  10560 polkitd   11w   REG    8,2        820 21165905 /var/lib/mysql/fef6fa81243e-slow.log

mysqld  10560 polkitd   12u   REG   0,42          0 74328020 /tmp/ibellVRU (deleted)

mysqld  10560 polkitd   13u  sock    0,9        0t0    65025 protocol: TCPv6

mysqld  10560 polkitd   14w   REG    8,2 1026029812 21165913 /var/lib/mysql/on.000004

mysqld  10560 polkitd   15u  sock    0,9        0t0    65026 protocol: UNIX

mysqld  10560 polkitd   16u   REG    8,2       2048 74317349 /var/lib/mysql/mysql/user.MYI

mysqld  10560 polkitd   17u   REG    8,2        452 74317350 /var/lib/mysql/mysql/user.MYD

mysqld  10560 polkitd   18u   REG    8,2       5120 74317346 /var/lib/mysql/mysql/db.MYI

mysqld  10560 polkitd   19u   REG    8,2        880 74317347 /var/lib/mysql/mysql/db.MYD

mysqld  10560 polkitd   20u   REG    8,2       5120 74317493 /var/lib/mysql/mysql/proxies_priv.MYI

mysqld  10560 polkitd   21u   REG    8,2       1386 74317494 /var/lib/mysql/mysql/proxies_priv.MYD

mysqld  10560 polkitd   22u   REG    8,2       4096 74317361 /var/lib/mysql/mysql/tables_priv.MYI

mysqld  10560 polkitd   23u   REG    8,2          0 74317362 /var/lib/mysql/mysql/tables_priv.MYD

mysqld  10560 polkitd   24u   REG    8,2       4096 74317364 /var/lib/mysql/mysql/columns_priv.MYI

mysqld  10560 polkitd   25u   REG    8,2          0 74317365 /var/lib/mysql/mysql/columns_priv.MYD

mysqld  10560 polkitd   26u   REG    8,2       4096 74317468 /var/lib/mysql/mysql/procs_priv.MYI

mysqld  10560 polkitd   27u   REG    8,2          0 74317469 /var/lib/mysql/mysql/procs_priv.MYD

mysqld  10560 polkitd   28u   REG    8,2       1024 74317358 /var/lib/mysql/mysql/servers.MYI

mysqld  10560 polkitd   29u   REG    8,2          0 74317359 /var/lib/mysql/mysql/servers.MYD

mysqld  10560 polkitd   30uW  REG    8,2      98304 74317489 /var/lib/mysql/mysql/slave_master_info.ibd

mysqld  10560 polkitd   31uW  REG    8,2      98304 74317491 /var/lib/mysql/mysql/slave_worker_info.ibd

mysqld  10560 polkitd   32uW  REG    8,2      98304 74317487 /var/lib/mysql/mysql/slave_relay_log_info.ibd

mysqld  10560 polkitd   33u   REG    8,2       2048 74317477 /var/lib/mysql/mysql/event.MYI

mysqld  10560 polkitd   34u   REG    8,2          0 74317478 /var/lib/mysql/mysql/event.MYD

mysqld  10560 polkitd   36u   REG    8,2     207872 74328024 /var/lib/mysql/test/products.MYI

mysqld  10560 polkitd   37u   REG    8,2 1024880000 74328025 /var/lib/mysql/test/products.MYD

mysqld 进程确实打开了大量文件

而根据文件描述符(FD)的编号,我们知道,描述符为 37 的是一个路径为/var/lib/mysql/test/products.MYD的文件,这里注意37后面的U表示,mysqld读写的方式访问文件
看到这个文件,熟悉 MySQL 的你可能笑了:

1、MYD 文件,是 MyISAM 引擎用来存储表数据的文件;
2、文件名就是数据表的名字;
3、而这个文件的父目录,也就是数据库的名字。

换句话说,这个文件告诉我们,mysqld 在读取数据库 test中的products表

7、查看 mysqld 在管理数据库 test 时的存储文件

?

1

2

[root@luoahong ~]# docker exec -it mysql ls /var/lib/mysql/test/

db.opt  products.MYD  products.MYI  products.frm

从这里你可以发现,/var/lib/mysql/test/ 目录中有四个文件,每个文件的作用分别是:

1、MYD 文件用来存储表的数据;
2、MYI 文件用来存储表的索引;
3、frm 文件用来存储表的元信息(比如表结构);
4、opt 文件则用来存储数据库的元信息(比如字符集、字符校验规等

8、这些文件到底是不是 mysqld 正在使用的数据库文件呢?

?

1

2

3

4

5

6

[root@luoahong mysql-slow]# docker exec -i -t mysql mysql -e 'show global variables like "%datadir%";'

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

| Variable_name | Value           |

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

| datadir       | /var/lib/mysql/ |

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

9、数据库中正在执行什么样的 SQL 了

不过,为了保证 SQL 语句不截断、这里我们可以执行 show full processlist命令。如果一切正常,你应该可以看到如下输出:

?

1

2

3

4

5

6

7

8

mysql> show full processlist;

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

| Id  | User | Host            | db   | Command | Time | State        | Info                                                |

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

| 183 | root | localhost       | NULL | Query   |    0 | init         | show full processlist                               |

| 188 | root | 127.0.0.1:60018 | test | Query   |    1 | Sending data | select * from products where productName='geektime' |

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

2 rows in set (0.00 sec)

10、explain 命令确认是否建立索引

根据这些信息,我们可以确定,这条查询语句压根儿没有使用索引,所以查询时,会扫描全表,并且扫描行数高达 20000 行。响应速度那么慢也就难怪了。

?

1

2

3

4

5

6

7

8

9

10

11

12

mysql> use test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> explain select * from products where productName='geektime';

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

| id | select_type | table    | type | possible_keys | key  | key_len | ref  | rows  | Extra       |

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

|  1 | SIMPLE      | products | ALL  | NULL          | NULL | NULL    | NULL | 20000 | Using where |

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

1 row in set (0.01 sec)

查询 products 表的结构

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

mysql> show create table products;

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

| Table    | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

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

| products | CREATE TABLE `products` (

  `id` int(11) NOT NULL,

  `productCode` text NOT NULL COMMENT '产品代码',

  `productName` text NOT NULL COMMENT '产品名称',

  `productLine` text NOT NULL COMMENT '产品线',

  `productScale` text NOT NULL,

  `productVendor` text NOT NULL,

  `productDescription` text NOT NULL,

  `quantityInStock` smallint(6) NOT NULL COMMENT '库存',

  `buyPrice` decimal(10,2) NOT NULL COMMENT '价格',

  `MSRP` decimal(10,2) NOT NULL COMMENT '建议零售价',

  PRIMARY KEY (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC |

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

1 row in set (0.01 sec)

你会看到,它只有一个 id 主键,并不包括 productName 的索引: 

11、创建索引 

?

1

2

mysql> CREATE INDEX products_index ON products (productName);

ERROR 1170 (42000): BLOB/TEXT column 'productName' used in key specification without a key length

你会看到,它只有一个 id 主键,并不包括 productName 的索引:就必须为 productName 指定一个前缀长度

?

1

2

3

mysql>  CREATE INDEX products_index ON products (productName(64));

Query OK, 20000 rows affected (38.83 sec)

Records: 20000  Duplicates: 0  Warnings: 0

现在可以看到,索引已经建好了。能做的都做完了,最后就该检查一下,性能问题是否已经解决了。

查看还在执行的 curl 命令的结果:

?

1

2

3

4

5

6

7

8

9

[root@luoahong ~]# while true; do curl http://192.168.118.115:10000/products/geektime; sleep 5; done

Got data: () in 8.62768268585205 sec

Got data: () in 8.635614395141602 sec

Got data: () in 8.58862042427063 sec

Got data: () in 22.183180809020996 sec

Got data: () in 0.19141674041748047 sec

Got data: () in 0.010161638259887695 sec

Got data: () in 0.006281137466430664 sec

Got data: () in 0.006078481674194336 sec

查看还在执行的 curl 命令的结果:

四、DataService 是一个严重影响 MySQL 性能的干扰应用

1、停止DataService容器

?

1

2

3

[root@luoahong ~]#

[root@luoahong ~]# docker rm -f dataservice

dataservice

2、删除索引

?

1

2

3

4

5

$ docker exec -i -t mysql mysql

mysql> mysql>

mysql> DROP INDEX products_index ON products;

Query OK, 20000 rows affected (16.24 sec)

Records: 20000  Duplicates: 0  Warnings: 0

3、观察性能

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

[root@luoahong ~]# vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

 1  0  35340 1429716      0 1131008    0    3 20224   421  409  517 10  5 70 16  0

 0  1  35340 1427952      0 1130840   16    0 110096     0  607  429  2 11 55 33  0

 0  1  35340 1429188      0 1130904    0    0 111368     0  583  361  1 11 50 38  0

 0  1  35852 1429212      0 1131276    0  388 93088   388  680  536  1 11 52 37  0

 2  0  36108 1427440      0 1131444    0  240 80744   240  624  390  3 13 50 35  0

 1  1  40716 1427952      0 1132732    0 4808 102312  4808  527  376  1  9 51 39  0

 0  0  40716 1430220      0 1132712    0    0 35228     0  331  335  1  5 78 16  0

 0  0  40716 1430220      0 1132712    0    0     0     0  123  210  0  0 100  0  0

 2  0  40716 1430220      0 1132712    0    0     0     0  124  202  1  1 99  0  0

 0  0  40716 1430220      0 1132712    0    0     0     0  142  226  0  1 99  0  0

 1  0  40716 1430220      0 1132712    0    0     0     0  194  246  1  2 97  0  0

4、观察 curl 的结果:

?

1

2

3

4

5

6

7

8

9

10

11

Got data: () in 13.258588314056396 sec

Got data: () in 9.701965808868408 sec

Got data: () in 9.14393663406372 sec

Got data: () in 9.088764190673828 sec

 

Got data: () in 5.43427038192749 sec

Got data: () in 5.0143187046051025 sec

Got data: () in 6.960656404495239 sec

Got data: () in 7.294579267501831 sec

Got data: () in 4.582106590270996 sec

Got data: () in 4.365068674087524 sec

作者:罗阿红 出处:http://www.cnblogs.com/luoahong/ 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值