PHPとMysqlでなんか動作が重たいな。って思ったら!

はまったはまった。 今まで静的ページで表示していたWEBページを動的に表示しようとPHPとMysqlを導入。 管理が非常に楽になりました。 必要な情報はDBに保存しPHP側でそれを処理しHTMLで吐き出す。 すごくやりやすいけど、ページが表示されるのが不思議と重たくなった。   DBの処理が増えれば増えるほど遅くなる。 なぜ??PHPの書き方、Mysqlへの接続、SELECT文ともに早く動作するように工夫しているのに…。 PHPのソースで不要なところは削除したり、Mysqlのインデックスを付けてみたり…ナノになぜこんなに重い。。。   そこで本日は、こういった状況に陥った時に確認すべき事項をメモ代わりに記述しました。  

●まず、第一にPHPは誰でも便利に使いやすいように非常にアバウトなコードでも動く!!

俺みたいな初心者プログラマーでも動くように設定されており、エラーが出ても動いてくれる。 なんてすばらしい!! …でも、その素晴らしい機能のせいで今回は苦しんでいるんです。。  

●クォートの扱いに注意!!

クォートで囲むと囲まないとで劇的な差が出ます。 関数内、配列、文字、ファイルパス等でクォートを使いますが、例えば、以下のように(例は関数の引数) function(“test”); function(‘test’); お分かりだろうか? そう!シングルとダブルの違い!これがバラバラでソース内で記述されていたらPHP側では、「どっちだろう」とアバウト補完を繰り返します。 そのアバウト補完を繰り返す分、動作が遅くなるのです。 ※これは他で使っている配列、文字、ファイルパスでも同様です。 $test[“test”] = “test”; $test[“test”] = ‘test’; $test[‘test’] = “test”; $test[‘test’] = ‘test’; どれも違う記述となります。 こんな初歩的な事で動作は重たくなってくるのです。 使用しているのが一か所だと問題ないのですが、この記述が多数あるとあればあるその分重たくなるのです。   解決策は、自分ルールを決める事です! 例えば、配列名ははシングルを使い、関数内ファイルパスなどの文字列はダブルを使う。 $test[‘test’] = “test”; include(“function.php”); $file_pas = “/var/www/homepage/index.php”; って風にね。 このルールを守って構築すれば、これだけで劇的に早くなります。 ※基本的には、文字にはダブル。配列にはシングルを使うと良いでしょう。    

●Mysqlのクォート使いにも気をつけよう!

PHPはアバウト処理をしてくれますので、クォートをつけなくても動くのですが、有るのと無いのとでは天地ほどの差が出ます!! なので四の五の言わず、”絶対に”つけよう。 ※付ける付けないで、5倍も10倍もパフォーマンスが違う。   Mysqlへの接続などのクォートはバッククォートです。 ちなみにキーボードのShiftを押しながら@を押したら入力できます。   select * from dbename where id = test order by date DESC(ないバージョン) select * from `dbename` where `id` = ‘test’ order by `date` DESC(あるバージョン) このバッククォートが大事なのです。 総称すると以下のようになります。 $sql = “select * from `dbename` where `id` = ‘test’ order by `date` DESC”;

※Mysql側のテーブル、カラム名、エイリアス名にはバッククォートを使用し、文字列にはシングル、変数代入にはダブルクォートを使用しましょう。

これだけでも劇的に変わります!!  

●PHPでの文字の扱いにも注意!

HTMLに文字を渡す場合もパフォーマンスが関係します。 以下の例だと、わずかだが後者の方がパフォーマンスが良い!   echo “このページのTitleは、”.$_GET[‘title’].”です”; echo “このページのTitleは、{$_GET[‘ititle’]}です。”;   {は、テキスト文中に変数を差し込みたい場合に変数間を大かっこで囲めばその中は変数として処理される。 ※記述の数が増えると前者の方が早いです。  

●アスタリスクの使い方。

Mysqlへのselectなどのsqlリクエストでよく使う、*(アスタリスク)。 全フィールドをよびだせるからついつい使いがちですが、これが重い原因のひとつです。   Mysql側では、全文検索を行うため、MySQL上に無駄な処理がかかり重たくなります。 Mysql側に無駄な処理がかからないようにするのが必要です。   必要なカラムのみ取得するようにするには、下記のようにすると良い! select `dbename`.`id` from `dbename` where `id` = ‘test’ order by `date` DESC   上記の2つで【クォート】と、select分での*をやめることである程度負荷は軽減できるはずです。  

●limitを使う

limit 直後の0というのは、ポインタといわれるものの位置で、いわゆる1件目(プログラム上は1ではなく0から)から、カンマの後の行数分出力してくれます。 表示される件数が減れば減るほど早くなるのはものの道理。 全文表示より件数を絞って表示したほうが速い!  

●文字検索する場合は、前方一致が良い!

前方一致であればあるほど、パフォーマンスが良くなります。 SQL文で、ワイルドカードを使えば自由に前方一致・後方一致・全文検索が行えます。 たとえば、 select * from `data` where `Name` like ‘山田太郎’ こう書きますと、完全一致タイプの検索になります。 select * from `data` where `Name` like ‘山田%’ こう書きますと、前方一致で、山田の後はどんな文字列が入っていてもOKという検索になります。 select * from `data` where `Name` like ‘%太郎’ これは後方一致、苗字はなんでもよく、【太郎】という名前の方を探します。 select * from `data` where `Name` like ‘%田%’ この際の前方一致【文字列%】であれば、それなりのパフォーマンスで検出できますが、後方一致や全文検索での部分一致タイプでは、著しくパフォーマンスは落ちます。  

結論!

どんな自分ルールを決定し、それに準じてソースを作成します。 そして些細なエラー(notic)なども解決してより良いソースを作れるようにしましょう!!
  • このエントリーをはてなブックマークに追加

コメントをどうぞ

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA