MySQL ちょっと上級チューニング

動作状況の検証方法や、設定ファイルのチューニングなど、お客様で可能な MySQL のチューニング方法をご紹介いたします。
  1. 時間のかかる SQL コマンドを特定したい場合、どうすればいいですか?(MySQL 4.0、4.1、5.0 共通)

    my.cnf ファイルに「log_slow_queries=ログファイル名」と記述します。デフォルトでは、実行に 10 秒以上かかった操作がこのログファイルに記録されます。実行時間を変更したい場合は、my.cnf ファイルに「long_query_time=秒数」を追加すれば、記述した秒数を超えた操作がログファイルに記録されます。

    [⇒個別ページで表示]
  2. 実行時間のかかるクエリを改善するためにはどうすればいいですか?(MySQL 4.0、4.1、5.0 共通)

    EXPLAIN コマンドを使用します。Key フィールドにコマンド実行時に使用されるインデックス、rows フィールドにコマンド実行時に読み取ったデータ数が出力されます。作成インデックスが key フィールドに表示され、インデックスを使用しない場合よりも、rows フィールドのデータ数が格段に少なくなっていれば、クエリ実行速度も上がります。

    [⇒個別ページで表示]
  3. 動作しているサーバの設定値、システム変数を見たい場合、どうすればいいですか?(MySQL 4.0、4.1、5.0 共通)

    MySQL に接続した状態で、「SHOW VARIABLES LIKE ‘システム変数名’;」コマンドを実行します。

    [⇒個別ページで表示]
  4. 現在のサーバの動作状況を調べたい場合、どうすればいいですか?(MySQL 4.0、4.1、5.0 共通)

    MySQL 4.0、4.1 では、MySQL に接続した状態で「SHOW STATUS LIKE ‘ステータス変数名’;」コマンドを実行します。
    MySQL 5.0.2 以上では、SHOW GLOBAL STATUS LIKE ‘ステータス変数名’;」を実行する必要があります。5.0.2 からは仕様が変更され、GLOBAL もしくは SESSION というオプションが指定できるようになりました。オプション省略時は SESSION が指定されたものと同じになるため MySQL 5.0.2 以降では、グローバルな情報を取得するには「SHOW GLOBAL STATUS LIKE ‘ステータス変数名’;」と明記する必要があります。

    [⇒個別ページで表示]
  5. 同じ SQL コマンドを実行する場合にパフォーマンスを向上させる方法はありますか?(MySQL 4.0、4.1、5.0 共通)

    クエリキャッシュを使用してください。(MySQL 4.0.1 から有効)my.cnf ファイルで「query_cache_type」を ON に、「query_cache_size」を 0 より大きな適切な値に設定すれば、実行結果がクエリキャッシュ内に格納されますそして同一の SQL が発行された場合には、キャッシュ内の結果が返されます。

    [⇒個別ページで表示]
  6. アクセスをするたびにテーブルを開く負担を軽減するにはどうすればいいのですか?(MySQL 4.0、4.1、5.0 共通)

    システム変数「table_cache」を大きくします。現在開かれるテーブルを示すステータス変数「Open_tables」に比べ、今まで開いたテーブルを示すステータス変数「Opened_tables」の値が著しく大きい場合、table_cacheの値を増やしてください。

    [⇒個別ページで表示]
  7. 多数のクライアントがアクセスする場合、接続にかかる時間を短縮するにはどうすればいいのですか?(MySQL 4.0、4.1、5.0 共通)

    システム変数「thread_cache_size」を大きくします。。新たにクライアントが接続した場合、スレッドキャッシュからスレッドを利用し、キャッシュにスレッドがない場合、新たにスレッドが作成されます。接続数を示すステータス変数「Connections」の値と、作成されたスレッド数を示すステータス変数「Threads_created」の値を比較し、Threads_createdの値が大きい場合「thread_cache_size」を増やしてください。

    [⇒個別ページで表示]
  8. 大規模なトランザクション処理を実行する場合、パフォーマンス低下を防ぐ方法を教えてください。(MySQL 4.0、4.1、5.0 共通)

    キャッシュに保存されるバイナリログのサイズを指定するシステム変数「binlog_cache_size」の値を増やしてください。

    [⇒個別ページで表示]
  9. インデックスがディスクから読み込まれるのを防ぎ、メモリから読み込まれるようにするにはどうすればいいのですか?(MySQL 4.0、4.1、5.0 共通)

    システム変数「key_buffer_size」の値を増やしてください。「Key_reads」ステータス変数は、インデックスがディスクから読み込まれる量、「Key_read_request」ステータス変数は、インデックスが、ディスク、バッファのどちらかから読み込まれる量を示しますが、「Key_reads / Key_read_request」の値が 1/100 より大きい場合は、ディスクから読み込まれる量が多すぎるため、「key_buffer_size」の値をより大きな値に変更してください。

    [⇒個別ページで表示]
  10. 大量のデータが格納されたテーブルから連続した特定のデータのみを取り出すにはどうすればいいのですか?(MySQL 4.0、4.1、5.0 共通)

    例えば、上から20行読み飛ばして、21行目から30行を取得したい場合、「SELECT * FROM t1 LIMIT 20, 30;」と実行します。これにより、効率的にデータを取得できます。

    [⇒個別ページで表示]
  11. 二つのテーブル t1、t2 を結合した SQL 文を EXPLAIN 文で見ています。MySQL サーバは、t2、t1 の順番で結合していますが、どうも t1、t2 の順番で結合した方が効率よく思われます。自分で結合順を指定することはできますか?(MySQL 4.0、4.1、5.0 共通)

    可能です。この場合、「SELECT STRAIGHT_JOIN * FROM t1,t2 WHERE ……;」と実行します。STRAIGHT_JOIN を指定し、FROM の後ろのテーブル名を自分の結合したい順に並べることで、結合順を指定できます。

    [⇒個別ページで表示]
  12. 更新系のコマンドと SELECT コマンドを同時に実行する場合、通常、SELECT コマンドよりも、更新系のコマンドが優先されます。更新系のコマンドよりも、SELECT コマンドを優先したい場合どうすればいいですか?(MySQL 4.0、4.1、5.0 共通)

    「SELECT HIGH_PRIORITY ….;」と実行します。

    [⇒個別ページで表示]
  13. 大量のデータを挿入したい場合、INSERT コマンドを繰り返すようにコーディングしてしまいました。より速く処理する方法はありますか?(MySQL 4.0、4.1、5.0 共通)

    何度も INSERT コマンドを繰り返すのではなく、「INSERT INTO t1 VALUES(1,”aaa”), (2,”bbb”), (3,”ccc”)…..;」のようにマルチプルINSERTに書き換えて一度で済ませるようにします。

    [⇒個別ページで表示]
  14. 大量のデータを挿入したテーブルを全部消したいと思います。WHERE 句なしの DELETE コマンドと、TRUNCATE TABLE コマンドではどちらが速いですか?(MySQL 4.0、4.1、5.0 共通)

    TRUNCATE TABLE コマンドの方が高速です。ただし、削除行数は DELETE コマンドでは正しく表示されますが、TRUNCATE コマンドでは正しく表示されませんのでご注意ください。

    [⇒個別ページで表示]