2013年5月26日日曜日

MySQLのパフォーマンス改善

過去の経験でMySQLのパフォーマンスが改善出来たものをご紹介。


  1. MySQLのインデックス設定忘れ
    小規模なサイトであれば、インデックスを忘れても気付かないものです。
    データが蓄積されると少しずつレスポンスが悪くなるので、たちが悪いです。
    インデックスの設定忘れは、レコード数が100とか1000レベルなら体感できないのですが、10000レコードを超えたあたりから、少しずつレスポンスが悪くなっていきます。

    小規模なサイトであれば、どれにインデックスを設定しよう?と悩むことなく、設定できるものは設定した方が良いと思います。
    インデックスを設定した際のデメリットは、データ追加コストの増加とデータの肥大化です。
    1回1回の追記処理にインデックス作成に時間がかかると言っても微々たるものですし、データが肥大化と言っても大したことはありません。
  2. DB接続の多用
    1つのphpファイルの中でDBへの接続・切断を繰り返すとレスポンスが悪くなります。
    接続は1回のみ、切断の処理は入れないほうがレスポンスが改善されます。
    接続の処理は入れなくても、phpの処理が終わると自動的に切断されます。
  3. DBの参照をlocalhostではなく、127.0.0.1に変更(OSがWindowsの場合)
    これは、Windowsで環境を構築している際に問題が発生します。
    WindowsVista、WindowsServer2008移行はIPv6が有効になっており、localhostで参照するとIPv6優先で接続を行おうとします。
    結果として、IPv6が使える環境は少ないので、v6で接続できずIPv4で接続を行います。
    このv6参照不可からv4で参照に切り替えるまでの時間がロスとなります。
    DBへの接続設定は、127.0.0.1をお勧めします。

    ・最初の1回だけサイトを開くのが遅い。
    ・OSをWindowsXPからWindowsVistaやWindows7に変更したら全体的に遅くなった。
    ・OSをWindowsServer2003から2008等に変更したら遅くなった。

    上記はサイト毎の設定ですが、OS側で対処を行えば、サイト毎の対処は必要でなくなります。
  4. Where句で日付を検索する際は、LIKE演算子ではなく、BETWEENを使う
    データの中から、今月のデータを参照する際、LIKE演算子を使うよりBETWEENが速いです。
    (インデックスを使用する為)

    以下は、2013年1月のデータを検索する際の例です。

    ・LIKE演算子を使う場合
    $sql = 'select * from table_name where date_field like "2013-01%"';

    ・BETWEEN演算子を使う場合
    $sql = 'select * from table_name where date_field between "2013-01-01" and "2013-01-31";

    betweenを使用する際の問題点としては、月末の日付を設定するのが面倒という事です。
    date関数で月の日数が取得できるので、以下のように指定しています。

    $year = 2013;
    $month = 1;

    $start_date = $year.'-'.$month.'-01';
    $end_date = $year.'-'.$month.'-'.date('t',strtotime($year.'-'.$month.'-01'));

    $sql = 'select * from table_name where date_field between "'.$start_date.'" and "'.$end_date.'"';














0 件のコメント: