InnoDBを使うときのパフォーマンスチューニング
ストレージエンジンとしてInnoDBを使うときはMyISAMのときと触るべきポイントが違うので注意。
http://www.mysqlperformanceblog.com/files/presentations/OSCON2004-MySQL-Innodb-Performance-Optimization.pdf
を読みながら取ったメモ。状況としてはRedHat AS3.0で動かしたときのDBT2*1のパフォーマンスを改善していくというもの。MySQL
デフォルト状態での分析
Handler_read_nextが多い、つまりrange scanかindex scanが多すぎる
slow query logで何が悪いかを引っかける
例では2秒以上処理にかかったqeuryを記録するようにしている
結果を分析
update文が遅かったけど、update文そのままではexplainできないので、同じwhere句のselectに変えて分析
単に高負荷で引っかかる奴も居るので注意
EXPLAIN SELECT no_o_id FROM new_order WHERE no_w_id = 3 AND no_d_id = 1
というEXPLAINで以下のような結果となった。
1 | SIMPLE | new_order | index | NULL | PRIMARY | 12 | NULL | 1543785 | Using where; Using index |
いきなり遅いクエリを見付けるのは難しい
遅いクエリを大量に流して、最適化して、再度負荷をかけて検討 show processlistで一般的なクエリを捕まえるのもよいチューニングの結果を確認
Handler_read_nextが低く抑えられているinnodb のステータスを確認
show innodb statusでinnodb特有のステータスが得られる FILE IOの項目- readが多すぎ!
もうちょっと詳細にinnodbのステータスを調査
BUFFER POOL AND MEMORYの項目
読み込みの6倍も書き込みがある それほど書き込みをするワークロードでもないのに defaultのinnodb_log_file_size=5MBが小さすぎる dirty pageのflushが多すぎる。これはもっと遅延できるはず ヒット率から言ってbuffer poolの量は悪くないより詳細な分析
open_tablesが多い
- table_cacheを増やす
innodb_thread_concurrencyを32に
- 目安は(num_disks+num_cpus)*2ぐらい
log I/Oが多いように見受けられる
- innodb_log_buffer_size=8M
スキーマに手を入れる
- new_ordery テーブルについて
- stockテーブルについて
テーブルの再構成
フラグメントを直したり主キーから引き易くしてくれる。 alter tableやoptimize tableでやってくれる。その他の使えるヒント
主キーにshort integerを使う
ランダムな主キーを使わない
ちょっと危険な方法
fsync(2)は信用できないことが多い*3 innodb_flush_log_at_trx_commit=0にするとcommit時にflushをしなくなる。 ただし、毎秒の1回のflushは実行されるswapを無効にする
2.6.7からswapの悪影響は無くなった 2.4系列なら切ると速くなる 2.6.7でswapを切っているとOOMが動くDirectI/Oのパフォーマンス
kernelのバッファを使わなくなるのでhugememの悪影響を軽減できるRAID10のブロックサイズ
大きな処理のときにはブロックサイズが大きい方が速いRAIDのlevel
RAID5は当然のことながら遅い RAID0は速いけど普通使わない RAID10がやっぱり良いのではまとめ
- 全部で100倍以上速くなった。