6月29日にMySQLウィークリーセミナーに参加してきました。 相変わらす、勉強会とかセミナーのまとめが遅いので反省です(PHP勉強会も残っているな。。。)。 当初の予想通りやはり人気があったらしく、急拠2回にわけて開催されることになりました。 最初の申し込みには間に合わなかったのですが、追加募集で滑り込むことができました。 パフォーマンスとは ・パフォーマンスの指標

  • スループット
  • レスポンスタイム/レイテンシ(遅延)
  • スケーラビリティ
  • 上記の組み合わせ

これらの指標について、平均値だけではなくばらつきも見る必要ある。 キューイング

  • 複数のユーザ/リクエストがある場合に発生
  • レスポンスタイム = キューイングによる遅延 + 実行時間
  • ホッケースティック(システムが飽和状態になると、キューイングによる遅延が急激に増大する現象)

パフォーマンスの改善時に、キューイングの遅延と実行時間のどちらを改善するか重要(実行時間の短縮がキューイングの遅延を改善する) 実行時間

  • ボトルネックの特定
    ・ネットワーク
    ・CPU
    ・ディスク
    ・ロック
    ・…
  • 間接的な計測
    ・webページ表示のためのクエリ実行時間の合計
  • 直接的な計測
    ・CPU利用率
    ・ディスクIOのレイテンシ
    ・ネットワークトラフィック
    ・処理待ちプロセス数
    ・同時実行中のクエリ数
    ・…

ベンチマークテストの注意点

  • 実行方法と、結果の読み取りを間違えると意味がなくなる
  • バージョンを変えると改善していることも
  • その他、ありがちな間違い
    ・データサイズが違う(本番10GBなのに1Gでテスト)
    ・データやリクエストのばらつきを考慮しない
    ・1ユーザだけでテストするとか
    ・実際の運用環境と違うアプリケーション特性下でのテスト
    ・ベンチマークテストのクライアントに負荷がかかっていて性能が出ない

パフォーマンスチューニングをする際の注意事項

  • 他の可能性を考える(メモリ増やすとか)
  • 本当にそのパフォーマンスが必要かどうか
  • 常に全体像を把握しておく(ボトルネックとか。)
  • チューニングのプライオリティーを確認しておく
    ・全部をやることは多くの場合無駄
    ・コストとのトレードオフ

パフォーマンスチューニングTIPs MySQL アーキテクチャは以下のようになっている。``` クライアント ↓ コネクションスレッドプール ↓ クエリキャッシュ ↓ パーサー ↓ オプティマイザ ↓ ストレージエンジン

↓はクエリの流れ


*   max\_connections(100)  
    ・コネクション数。多すぎるとメモリを消費しすぎるかも  
    ・一般的なweb計のシステムでは1000強に設定し、有事に備えサーバには2倍の余裕を持たせておく
*   thread\_cache\_size(8)  
    ・一般的には max\_connectons/3  
    ・スレッドをコネクションの切断後にキャッシュしておく数

show status like ‘Thr%’


*   sort\_buffer\_size(2M)
*   メモリサイズの見積もり = max\_connectons x (スレッドごとのバッファ\*thread\_stack) \* 1/2

**クエリキャッシュ**

*   query\_cache\_size(0)  
    ・クエリキャッシュに割り当てるメモリサイズ  
    ・まったく同じクエリのときにキャッシュを使う  
    ・一般的には32Mくらい

**ストレージエンジン** ストレージエンジンごとのチューニング ・InnoDB 特性は[前回](http://wadslab.net/2008/06/mysql_study/)を参照

*   innodb\_buffer\_pool\_size  
    ・MySQL&InnoDBのみ利用ならばメインメモリの80%を割り当てる  
    ・データとインデックスの両方をキャッシュ
*   innodb\_log\_file\_size  
    ・innodb\_buffer\_pool\_sizeの25~100%くらい  
    ・ログファイルがどの程度頻繁に切り替わっているかをチェック  
    ・値を大きくするとクラッシュ時のリカバリ時間が長くなる
*   innodb\_flush\_log\_at\_trx\_commit  
    ・基本的には変えないほうがよい

DBの稼動情報は```
SHOW INNODB STATUS;

```で確認 ・MyISAM

*   key\_buffer\_size(8M)  
    ・MySQL&MyISAMのみ利用ならばメインメモリの25~33%くらい
*   myisam\_sort\_buffer\_size(8M)  
    ・インデックス作成時には大きくしておく
*   myisam\_recover=FORCE,BACKUP  
    ・テーブルアクセス時に破損をチェック
*   delay\_key\_write=ALL  
    ・インデックスをディスクに反映させるのをテーブルが閉じられたタイミングのみにする  
    ・クラッシュ時にデータが破損する可能性が高くなるので注意が必要

DBの稼動状況は```
show status lile 'key%'

```**インデックス**

*   参照時の性能は向上するが、更新時はオーバーヘッド(インデックスも更新するため)
*   インデックス内での順序が先の列のみ利用可能  
    ・key(a,b) ... where b=5 はインデックスを使わない
*   必要最小限にとどめること  
    ・ばらつきが少ないデータはインデックスが使われない場合がある(が、更新時にはオーバーヘッド)  
    ・性別などに使うのは。。。
*   ユニークなインデックスにはUNIQUEをつける
*   重複するようなインデックスは避ける  
    ・key(a,b)があるならkey(a)はは削除

**チューニングに関するコマンド&SQL** SQLオプティマイザの制御```
SELECT STRAIGHT\_JOIN \* from tbl1, tbl2...

```SQL文に書かれたテーブルの順に処理を行う```
 USE INDEX or FORCE INDEX or IGNORE INDEX

ANAYZE TABLE


*   EXPLAINでオプティマイザの解析結果を確認
*   スロークエリを有効に  
    ・--log-slow-queries --long-query-time=2 --log-long-format  
    ・mysql\_explain\_log ログの内容を表示するコマンド(5.0のみ)  
    ・mysqldumpslow ログの内容を集計するコマンド
*   開発環境では一般ログ(general query log)も利用  
    ・クエリの重複や数が多すぎないか
*   SHOW \[FULL\] PROCESSLIST  
    ・遅いクエリ、終わらないクエリを検出
*   クエリが実際に行っている内容の確認  
    ・FLUSH STATUS; ; SHOW STATUS;

**ハードウェア関連のチューニング** ハードウェアの選択

*   CPU:64bit CUPの利用を検討
*   CPUキャッシュ 大きいほうがよい
*   Memoryバンド幅 CPU利用が中心の処理の際にネックになる
*   CPU数/コア数/スレッド数 ひとつのクエリはひとつのCPUを使用

**その他** 結構好評だったので、今後SUNのオフィスで継続していくことを検討しているらしい。 **感想** パフォーマンスチューニングの初歩的な内容でした。自分のレベルにあっていてちょうどよかったです。 ここでのことをちゃんとやれば一般的なウェプサービスでは対応できそうですね。