MySQL5.7と5.1の速度パフォーマンスを比較してみたときのメモ

# やりたいこと
  MySQL5.1と5.7でどのくらいパフォーマンスが違うのか計測してみる。
  書き込み、読み込みでどのくらい違うのか比較したいため、
  readとwriteのパフォーマンスと、innodbとMyISAMのパフォーマンスを
  それぞれ比較検証する。

# 負荷テストツールの選定
  負荷をかけるにあたって、テストツールは、今回はmysqlslapを使うことにした。
  supersmackを使うことも考えたが、細かいシナリオを組む必要もなかったので、
  さくっと、mysqlslapでテストを実施する

# 検証サーバのスペック

> CPU 4コア、メモリ8G
> CentOS release 6.4 (Final)

# テスト
## write（InnoDB）

### テスト内容
  50〜150並列でクエリを流すことを複数回繰り返す

### MySQL5.1

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 5.980  | 5.889  | 6.054 | 
| 60 | 7.050  | 6.991  | 7.169 | 
| 70 | 8.179  | 8.077  | 8.310 | 
| 80 | 9.310  | 9.138  | 9.539 | 
| 90 | 10.527  | 10.308  | 10.716 | 
| 100 | 10.527  | 10.308  | 10.716 | 
| 110 | 12.843  | 12.791  | 12.932 | 
| 120 | 13.890  | 13.633  | 14.024 | 
| 130 | 15.257  | 15.035  | 15.510 | 
| 140 | 17.329  | 16.195  | 18.820 | 
| 150 | 17.503  | 17.382  | 17.683 | 


### MySQL5.7

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 1.051  | 0.971  | 1.137 |
| 60 | 1.258  | 1.211  | 1.336 |
| 70 | 1.683  | 1.581  | 1.781 |
| 80 | 1.699  | 1.603  | 1.831 |
| 90 | 1.759  | 1.647  | 1.928 |
| 100 | 1.604  | 1.519  | 1.731 |
| 110 | 1.970  | 1.890  | 2.073 |
| 120 | 2.329  | 2.257  | 2.409 |
| 130 | 2.586  | 2.440  | 2.676 |
| 140 | 2.575  | 2.516  | 2.676 |
| 150 | 2.650  | 2.525  | 2.783 |

### 結果
  InnoDBテーブルのwriteクエリに関しては、5.7の方が圧倒的に速い結果となり、5倍以上の差が出た。
  特に、5.1に関しては、50並列と150並列での処理速度が3倍遅くなっているのに対して、
  5.7では2.5倍ほどと、全体の処理速度が速いだけでなく、並列数が増えたときの速度も劣っていなかった。

## read（InnoDB）

### テスト内容
  10万クエリを50〜150並列で実行させる

### MySQL5.1

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 7.422  | 7.415  | 7.430 |
| 60 | 7.365  | 7.347  | 7.380 |
| 70 | 6.823  | 6.795  | 6.854 |
| 80 | 6.764  | 6.717  | 6.792 |
| 90 | 6.541  | 6.533  | 6.556 |
| 100 | 6.391  | 6.272  | 6.453 |
| 110 | 6.397  | 6.387  | 6.402 |
| 120 | 6.305  | 6.294  | 6.317 |
| 130 | 6.253  | 6.242  | 6.268 |
| 140 | 6.202  | 6.197  | 6.209 | 
| 150 | 6.034  | 5.816  | 6.146 |

### MySQL5.7

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 3.104  | 3.101  | 3.109 |
| 60 | 3.129  | 3.127  | 3.133 |
| 70 | 3.186  | 3.107  | 3.276 |
| 80 | 3.158  | 3.105  | 3.227 |
| 90 | 3.140  | 3.095  | 3.178 |
| 100 | 3.137  | 3.117  | 3.168 |
| 110 | 3.160  | 3.137  | 3.177 |
| 120 | 3.192  | 3.134  | 3.261 |
| 130 | 3.164  | 3.133  | 3.187 |
| 140 | 3.158  | 3.097  | 3.269 | 
| 150 | 3.123  | 3.111  | 3.134 |

### 結果
  InnoDBテーブルのreadクエリでは、パフォーマンスが2倍ほど、5.7の方が速い結果になった。
  並列数が重なっても、大きく処理の遅延が起きることなく、150並列程度であれば、問題なく捌けていた

## write（MyISAM）

### テスト内容
  50〜150並列でクエリを流すことを複数回繰り返す

### MySQL5.1  

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 0.010  | 0.010  | 0.011 |
| 60 | 0.013  | 0.012  | 0.017 |
| 70 | 0.015  | 0.014  | 0.017 |
| 80 | 0.032  | 0.015  | 0.067 |
| 90 | 0.032  | 0.015  | 0.067 |
| 100 | 0.037  | 0.017  | 0.077 |
| 110 | 0.022  | 0.021  | 0.024 |
| 120 | 0.035  | 0.030  | 0.045 |
| 130 | 0.082  | 0.055  | 0.131 |
| 140 | 0.116  | 0.084  | 0.161 |
| 150 | 0.131  | 0.114  | 0.140 |

### MySQL5.7

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 19.898  | 19.826  | 19.978  |
| 60 | 23.847  | 23.728  | 23.978  |
| 70 | 27.788  | 27.679  | 27.880  |
| 80 | 32.111  | 31.807  | 32.088  |
| 90 | 36.092  | 35.866  | 36.251  |
| 100 | 40.031  | 39.817  | 40.227 | 
| 110 | 43.938  | 43.799  | 44.037 |

### 結果

  MyISAMテーブルのwriteクエリでは、5.7が極端に遅い結果となった。
  こんなはずはないと思い、いろいろ調べたところ、sync-binlogが影響しているみたい。

### sync-binlogにハマる
  5.7に関しては、sync-binlogのデフォルト値が1となっており、
  こいつのせいで、パフォーマンスが極端に落ちていた。

  1以上の整数でこいつが設定されていると、N回バイナリログに更新を行なうごとに、
  ディスクのフラッシュ（同期）を行なうことになり、
  
  最も安全な更新にはなるが、ディスクへの負荷は高くなり、
  スペックが高くないサーバを使っていると、この負荷によりパフォーマンスが
  極端に落ちる可能性がある。

  そのため、sync-binlogを0に設定すると、セッション内でのバイナリログを無効に
  できるため、発生したDDLやDMLのディスクへの明示的な同期は行われず、
  同期タイミングはOSに委ねられることになる。

  以上のことから、今回は1にするケースではなかったため、
  sync-binlogを0に変更して、再度テストを行なった。

### MySQL5.7（*cnf変更後）

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 0.016  | 0.012  | 0.023 |
| 60 | 0.020  | 0.017  | 0.026 |
| 70 | 0.020  | 0.017  | 0.024 |
| 80 | 0.032  | 0.021  | 0.039 |
| 90 | 0.030  | 0.023  | 0.043 |
| 100 | 0.030  | 0.028  | 0.034 |
| 110 | 0.032  | 0.032  | 0.033 |
| 120 | 0.039  | 0.036  | 0.044 |
| 130 | 0.044  | 0.042  | 0.047 |
| 140 | 0.045  | 0.042  | 0.048 |
| 150 | 0.053  | 0.049  | 0.058 |

### 再度、結果
  sync-binlogを0にした結果、極端にパフォーマンスが悪化する状態は免れた。
  比較の結果、5.1の方が、50〜80並列までは速かったが、
  並列数が90を超えると、5.7の方が速いという結果となった

## read（MyISAM）

### テスト内容
  10万クエリを50〜150並列で実行させる

### MySQL5.1

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 1.420  | 1.419  | 1.421  |
| 60 | 1.421  | 1.421  | 1.421  |
| 70 | 1.438  | 1.427  | 1.446  |
| 80 | 1.427  | 1.419  | 1.442  |
| 90 | 1.421  | 1.418  | 1.424  |
| 100 | 1.423  | 1.421  | 1.428  |
| 110 | 1.447  | 1.428  | 1.484  |
| 120 | 1.685  | 1.577  | 1.816  |
| 130 | 4.359  | 2.770  | 5.383 | 
| 140 | 9.075  | 8.715  | 9.539 |
| 150 | 10.861  | 10.652  | 11.130 |

### MySQL5.7

| 並列数 | average | min | max(sec) | 
|:-----------:|-----------:|------------:|-------------:|
| 50 | 2.057  | 2.054  | 2.062 |
| 60 | 2.051  | 2.048  | 2.055 |
| 70 | 2.053  | 2.053  | 2.053 |
| 80 | 2.053  | 2.051  | 2.058 |
| 90 | 2.057  | 2.053  | 2.064 |
| 100 | 2.056  | 2.052  | 2.064 |
| 110 | 2.064  | 2.052  | 2.083 |
| 120 | 2.056  | 2.049  | 2.070 |
| 130 | 2.057  | 2.051  | 2.066 |
| 140 | 2.060  | 2.055  | 2.069 |
| 150 | 2.062  | 2.057  | 2.066 |

### 結果
  MyISAMテーブルのreadクエリでは、5.1の方が50〜120並列までは、
  5.7と比較して速く、130並列を超えると、パフォーマンスが著しく落ちる結果
  になった。5.7に関しては、全体的に並列数が増えても、2.0台で安定していた。

## まとめ
  今回のテストでは、mysqlのバージョン違いでのパフォーマンスを、
  mysqlslapを用いて、さくっとテストした。  

  実際の運用では、データベースやテーブルの構造によって、テストシナリオを
  考えて実行する必要があると思うが、
  全体的なパフォーマンスは、5.7の方が圧倒的に速い結果となった。

  だが、5.6から5.7に上がったタイミングで、設定のデフォルト値が変更に
  なっていたり、幾つかの項目が新しく加わっていたりするので、5.7の導入前には
  安定稼働できる状態になっているか、負荷テストを必ず行なうようにしたい。