PHPとMySQLを用いてシステム開発をしています。

xampp最新版でローカルで開発していますが、疑問がありましたので質問させて下さい。

【質問abstruct】
phpでフォームデータを投稿して同じページにアクセスして処理を行う場合、投稿前とデータが変わらないフィールドについて「hiddenタグ+$_POSTで前ページからの情報を引き継ぐ」のと、「mySQLにアクセスして情報を受け取る」のとでは、ごく大雑把に、一般的に言ってどちらが早いですか?尚、データが変わったフィールドについては、いずれにせよmySQLのstatusというフィールドを更新することになります。

【質問detail】
現在、statusという名前のDBでステータス管理をしています。そこでセッションのようなものを作成して、idやname等10項目、合計40chars程の情報を管理し、次画面で表示したり利用したりしています。フォーム投稿により、いくつかの項目が変化しますが、変化しない項目の方が多いです。

【質問更に詳細】
コメント欄に示す。

よろしくお願いします!

回答の条件
  • 1人3回まで
  • 13歳以上
  • 登録:2010/10/24 14:37:12
  • 終了:2010/10/29 22:19:17

ベストアンサー

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492010/10/24 16:29:02

ポイント120pt

hidden項目の有無はありますが、いずれの場合もフォームからの投稿を受け付けるという処理は発生してますので応答速度の早い順に下記のような具合になりますが、体感できるほどの速度差にはなりません

1.【例1】処理増加はphpがPOSTを受け取る項目増の分だけ

2.【例2】データベースからphpの変数へ読み込むため若干遅くなる

3.【phpのセッション変数利用】クッキーのやりとりが入りますのでクライアント-サーバ間の通信が若干増えますがデータの安全面から、これを採用するほうが無難でしょう

 

サーバの動作として軽い順は下記のような具合になります

1.【例1】

2.【phpのセッション変数利用】

3.【例2】

 

 

まったくの余談ですが、MySQLからのデータ抜き出しは下記のような具合にすればよろしいかと思います

$sql = "SELECT * FROM status WHERE id = '$id' LIMIT 0,1";
if( $result = mysql_query( $sql ) ){
    if ( mysql_num_rows( $result ) == 1) {
        $item = mysql_fetch_array( $result, MYSQL_ASSOC );
    }
}

・LIMITをつけることでMySQL側の処理時間短縮になります

・$name = $item['name'];のような処理を項目数分だけ行うのは効率悪いので、連想配列のままで使う事を考えたほうが良いでしょう

・連想配列としてのみ使うのであればMYSQL_ASSOCをつけておくと良いでしょう

・Webフォームの処理のような短時間で単純な接続の場合はmysql_free_resultを行う分だけ時間的ロスとなる場合も多いため自動開放に任せたほうが良いでしょう

 

http://dev.mysql.com/doc/refman/5.1/ja/select.html

http://www.php.net/manual/ja/function.mysql-free-result.php

http://www.php.net/manual/ja/function.mysql-num-rows.php

id:ReoReo7

ありがとうございます!

詳しい回答でプログラミングの指針が立ち、大変助かりました。

それと、データ抜き出しのコードも示して頂いてありがとうございます。

結果表示に1秒くらいかかってしまうので、ブラウザの描画の問題なのか、DBアクセスのコードが悪いのか分からず悩んでいたので助かりました。

まだチョット遅いですが、おかげさまでSQL文をひとつ削ることができ、高速化の目処がたちました!

2010/10/24 19:57:32
  • id:ReoReo7
    【質問更に詳細】
    例1のように「セッションをhiddenタグで隠し持ってフォームで一緒に投稿されることで次の画面に引き継ぎ、セッションが切れた場合のみstatusにアクセスして項目全部を読み取る」プログラムと、例2のように「フォームでhiddenタグを使わず、次の画面に進み、次の画面でstatusにアクセスしてid等を読み取る」のとではどちらが早いですか?

    【例1】
    $id = $_POST['id']
    $name = $_POST['name']
     :
    に加えてフォームに
    <input type="hidden" name="id" length="6" size="0" value="$id">
    <input type="hidden" name="id" length="6" size="0" value="$name">
     :
    を追加。

    【例2】
    例えばidというキーと更新したいデータ項目だけを$_POSTで受け取り、
    $sql = "SELECT * FROM status WHERE id = '$id'";
    $result = mysql_query($sql);
    if($result){

    while ($item = mysql_fetch_array($result)){
    $name = $item['name'];

    }
    mysql_free_result($result);
    }
    等のように、いちいち読み取って表示する。

    【想定する運用環境】
    XREA CORE SERVERの一番安いプラン「core-mini」
    http://www.coreserver.jp/
    クライアント側ブラウザ:IE8やFireFox最新版等の通常のブラウザ。
  • id:ReoReo7
    「MySQLにSELECTキューを投げて結果を格納する」スピードと、「hiddenタグで変化の無い40~400chars程度のデータを次ページに引き継いて、SELECTキューでMySQLにアクセスする時間を削り、そのかわり$_POSTで受け取って結果を格納する」というスピードを単純に比べています。

    データベースに投げた命令のlogのようなものを格納しているので、最大400chars、何も無い場合は40charsとちょっと幅が広いですが、400charsのほうを想定して下さって構わないです。

    ごく一般的に言えることだけで構いません。
  • id:ReoReo7
    ちなみに、クライアント側の接続はちょっと遅いです。
    一番遅い時で 上り100kbps/下り最大3Mbps程度。
  • id:ReoReo7
    ちなみに「MySQLにINSERT文を発行する」の動作はいずれにせよ必ず行ないます。
  • id:ReoReo7
    「MySQLにSELECTキューを投げて結果を格納する」について、
    statusのデータ構造ですが、フィールドが10程度、行数は1行になります。
    これは将来的にも10行程度にしかなりません。CSVの方が早ければご指摘下さればそうします。
    尚、statusのフィールドには最大400chars程度に達するlogも含まれます。
  • id:windofjuly
    うぃんど 2010/10/24 20:58:57
    >結果表示に1秒
    >ブラウザの描画の問題なのか、DBアクセス
     
    【OS環境の問題】他の常駐ソフトが結構重い
    他のソフトは停止しておいたほうが良いです
    PCを複数台保有している場合はサーバは別PC上に構築するとさらに良いでしょう
     
    【データベースの問題】インデックスが付いてない
    インデックスが無い場合、毎回全てのレコードを検索していきますのでレコード数が増えれば増えるほど1回のSQLにかかる時間は増大します
    idフィールドなど、検索に頻繁に使う項目には必ずインデックスをつけましょう
     
    【phpの問題】作成したphpスクリプトで無駄な部分がある
    phpでは1つの事を実現する手段がいくつも存在してますので、状況に応じて何を選ぶべきかでパフォーマンスが大きく変わってきます
     
    【ブラウザの問題】複雑な表組みなどで描画に手間取っている
    phpが出力するHTMLにはDTDなどが含まれていませんのでブラウザにあわせて適当なものを出力しておくほうが良いです
    長大なテーブルやDIVの入れ子などの場合は幅や高さを指定してFIXにするなどの工夫が必要な場合もあります
    その他、HTMLを高速表示するためのパフォーマンスチューニングを学ぶ必要があります
     
    どれも即座に身に付くようなものでもありませんので、1つずつ潰していってください

    phpの処理でどの程度の時間がかかっているかを計るには下記のようにする方法などがありますのでDBアクセスが気になるならば、前後に入れてみると判りやすいかもしれません
      $time = microtime(true);
      処理
      echo round(microtime(true) - $time, 2) . "秒<br />\r\n";
  • id:ReoReo7
    コメントありがとうございます。

    【OS環境の問題】他の常駐ソフトが結構重い
    他のソフトは停止しておいたほうが良いです
    PCを複数台保有している場合はサーバは別PC上に構築するとさらに良いでしょう

    →これが最も怪しい原因だと思います。ハードディスク空き容量が15%未満なので、デフラグが完全ではないことなどが影響して他のアプリもたまに遅くなることがあります。頻繁にデフラグはしてますが・・ いらない常駐ソフト停止&別パソコンにての試験了解です。あと、ウイルス対策ソフトはセキュリティの関係上、常駐させておいた方が良いですよね?


    【データベースの問題】インデックスが付いてない
    インデックスが無い場合、毎回全てのレコードを検索していきますのでレコード数が増えれば増えるほど1回のSQLにかかる時間は増大します
    idフィールドなど、検索に頻繁に使う項目には必ずインデックスをつけましょう

    ●ありがとうございます。これは何とか独学によりPRIMARYをIDにするとか、検索にかかるものはINDEXにする等しています。
     
    【phpの問題】作成したphpスクリプトで無駄な部分がある
    phpでは1つの事を実現する手段がいくつも存在してますので、状況に応じて何を選ぶべきかでパフォーマンスが大きく変わってきます

    ●あり得ると思います・・・処理全体は大雑把に分けて、入力された変数の判断&分岐処理とそれを記録したり変数を取り出したりするMySQL関連の処理です。例えば先に指摘して頂いたSELECT構文なんかでも改善点がありましたよね。
    プログラムスキルはVBAとC言語で初級と中級の中間といったところだと思います。一応コードは改行やタブに気をつけて見やすいようにしていて、重複する表現はなるべく関数化していますが、グローバル宣言はしていないので引数渡しの時間がかかり過ぎないよう、if~elseの分岐の条件判定の変数が違うだけ、のような細かい重複処理は関数化せずメイン関数の中に書いているので(引数をいくつか設定すれば関数化できる部分もあるのですが。)、まだまだ行数は関数化して削れるのかもしれません。
    ちなみにデータ長1700STEPです。自分のためにまとめると、内訳は
    *関数100STEP×6=600STEP
    *メイン関数900STEP(うちprintの記述に70行程度)
    *HTML描画(フォーム)ボタン1つにつき20行(hiddenタグで10行)×10ボタン=200行、
    →一つの処理を初めから終わりまで分岐をスムーズにたどれば50STEP(メイン処理を20STEP、関数3つを10STEP×3)程度だと思います。表示はコメント10行程度と入力フォーム1個とボタン10個、hiddenタグ100行程度を含む。hiddenタグは一つのフォームにつき400charsのフィールドデータの値を含むので、htmlは合計で5000chars程度を読み込むことになる(高速化するためにhiddenタグで次画面にデータを引き継ぐためのつもりが、さすがに5000charsだとクライアントによっては重くなる?)。

    【ブラウザの問題】複雑な表組みなどで描画に手間取っている
    phpが出力するHTMLにはDTDなどが含まれていませんのでブラウザにあわせて適当なものを出力しておくほうが良いです
    長大なテーブルやDIVの入れ子などの場合は幅や高さを指定してFIXにするなどの工夫が必要な場合もあります
    その他、HTMLを高速表示するためのパフォーマンスチューニングを学ぶ必要があります

    ●HTML描画は、DIV等使わず平文の文章ベタ打ちのコメントが5行、フォームも加工せず背景色も何も無く、入力フォーム1つとボタンを10個程度表示しています。恐らく描画の速度はそれほどかかってはいないと思います。

    phpの処理でどの程度の時間がかかっているかを計るには下記のようにする方法などがありますのでDBアクセスが気になるならば、前後に入れてみると判りやすいかもしれません
      $time = microtime(true);
      処理
      echo round(microtime(true) - $time, 2) . "秒<br />\r\n";

    ●やってみました。
    通常の処理で0秒、UPDATEすると0.01秒、INSERTすると0.01~0.03秒です。
    見た目より速いですね。。(笑)ということで、PCのパフォーマンスの問題という可能性が濃厚になってきました。。重いというのはIE8でしたが、再起動してから同一環境で試してみました。実感では0.5秒くらいに短縮されたようです。phpの方は相変わらず0.01秒~0.03秒。メモリは1GB、CPUは3GHz、HDDは35GB/40GB使用中。HDDの掃除かな・・・?(笑)
  • id:ReoReo7
    あっもしや音楽の読み込みに時間がかかっているのかな。音楽無しを試してみます!
  • id:ReoReo7
    結局通信速度の問題が大きいことが分かりました。
    音楽を1K程度に圧縮することで、携帯からのアクセスでも送信→受信まで2秒以下で実現できました。ありがとうございました。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません