ある程度大きなサービスを作る場合、データベース関連がボトルネック、となるケースはけっこう多いです。
この記事では、MySQLの場合のチューニングの仕方を説明します。なお、MySQLのバージョンといしてはバージョン5.1.58を想定しています。
1.チューニングの流れ
MySQLのチューニングの流れとしては、1.slow.logを利用して、ボトルネックの特定→2.チューニング→3.ベンチマーク、というようになります。
2.slow.logの取り方
slow.logを 取るには、my.cnfファイルに次の記述を行います。
long_query_time=3 log-slow-queries=/var/log/slow.log
この場合だと、/var/log/slow.logが生成されます。
これにより、3秒以上(秒数は、long_query_time、で指定)処理に時間のかかるクエリの特定が可能になります。そのクエリをボトルネックとしてチューニングを行なっていきます。
3.チューニング
チューニングの方法には、大まかに分けて1.クエリの最適化、2.データベース内部の設定用変数の最適化、3.周辺機器の増設、となります。
3-1.クエリの最適化
まずはクエリ自体を見直しましょう。パフォーマンスの良いクエリ、を目指すには「必要以上に多くのデータを取得しない」というのがまず初めの方針となります。
システム毎に最適なクエリというものは変わりますが、「クエリにlimit句を追加して、必要以上のレコードを取得しないようにする」「”select *”を使用しないようにする」ということを心がけるとクエリのパフォーマンスは大体において良くなります。
3-2.データベース内部の設定用変数の最適化
MySQLのコンソールで、
mysql>SHOW VARIABLES;
と入力することで、 MySQL内部で使われている設定用の変数とその値を確認できます。
また
mysql>SET GLOBAL 変数 = ○○;
と入力することで、変数の値を変えることができます。
チューニングのために見たほうが良い変数と一般的に推奨される値を示します。
■key_buffer_size
インデックスを保存するバッファのサイズを表します。MyISAMならばOSキャッシュも使うので256MBほど取れば良いでしょう。
例)mysql>set global key_buffer_size = 268435456
■innodb_buffer_pool_size
InnnoDBのバッファのプールサイズを表します。InnnoDBはOSキャッシュを使わないので総メモリの70-80%ほどを設定すると良いでしょう。
■table_open_cache
テーブルを開くときに使われるキャッシュ数を表します。I/Oタイムを減らすのに有効です。レコードの数が数百程度のテーブルなら1024がベストです。
■thread_cache_size
スレッドのキャッシュに使われるキャッシュ数を表します。スレッドの作成・削除は負荷重いので少なくとも16は欲しいです。
■innodb_log_file_size
ログファイルのサイズ。増やすとパフォーマンスが良くなりますが復旧に時間かかります。64-512MBくらいで調整すると良いでしょう。
■innodb_log_buffer_size
ログのバッファサイズを表します。デフォルトで十分です。あまり増やしすぎない方が良いでしょう。
■innodb_flush_log_at_trx_commit
設定しないと激しく遅くなります。flush logをディスクにとるかメモリかとらないかを選択します。1がディスク、2がメモリ、0がとらない。2が最適です。
■max_allowed_packet
入力データ保持のための最大バッファサイズです。大きなファイルを入出力する際に必須です。1MBほど取っておけば良いでしょう。
■sort_buffer_size
ORDER BYやGROUP BYのクエリ速度を上げます。メモリが多くない限りあまり必要ありません。
■long_query_time
この秒数を超えるとslowクエリに認定します。1が標準的でしょう。
■join_buffer_size
join用のバッファサイズを指定します。1MBほど取っておけば良いでしょう。
■query_cache
クエリのキャッシュ量。増やしすぎると更新が反映されない場合もあるのであまりよくありません。データベースのサイズに合わせて32MB-512MBくらいがベストです。
3-3.周辺機器の増設
上の2つのチューニングを行なっても効果が現れない場合、周辺機器(メモリやハードディスク)の増設を行なっても効果が期待できます。
3.ベンチマーク
SHOW GLOBAL STATUSやEXPLAINを用いて検索のベンチマークを取って行きます。それぞれのシステムによって、最適な値は変わりますのでこの辺りはお好み、となります。
4.参考文献
この記事を書くにあたり、次の図書を参考にしました。
1.B.Schwartz,P.Zaitsev,V.Tkacbenko,J.D.Zawodny,A.Lentz,D.J.Balling 伊藤直也,田中慎司,吉川英興監訳 株式会社クイープ訳(2009)『実践ハイパフォーマンスMySQL』 オライリー・ジャパン