saveCountersの外観に関するアナウンスを読んだ後、既存の機能の単なるラッパーであると思いました。 メソッドのドキュメントも、パフォーマンスを改善するためのマニュアルも、速度に関するその機能については何も述べていません。 一般的に、読んで忘れていました。
多くの場合、一部のデータを定期的に集約する必要があるタスクがあります。 私の場合、それは単純なバナーのひねりでした。 バナーが表示されると、生のテーブルに行が追加されました。 クラウンでスクリプトが呼び出されました。スクリプトはサイクルで生データを実行し、特にバナーのインプレッション数を増やしました。 ループ内には次のコードがあります。
$banner->hits++; $banner->save();
すべてがうまくいきましたが、負荷とともに問題が増え始めました。 クラウンスクリプトは時間切れになり、タイムアウトによって低下し始めました。 プロファイリングと科学的調査の過程で、スクリプトロジックが変更され、上記のコードフラグメントを除くすべてが変更されました。 彼は疑う余地がありませんでした。 結局のところ、無駄でした。
そのとき、特別なsaveCountersメソッドを思い出しました。 コードをこれに置き換えると、スクリプトのパフォーマンスに関するすべての問題が解決されました。
// " "=>" " $banner->saveCounters(array('hits'=>1));
この問題の解決策に驚いたので、メソッドのパフォーマンスを比較し、コードを調べることにしました。
テスト環境:core2 6420、ram 3gb、標準設定のZend Server CE 5.5。
テストコード:
$start = microtime(true); for($i=0;$i<1000;$i++) { $banner->hits++; $banner->save(); $banner->saveCounters(array('hits'=>1)); } echo microtime(true)-$start;
いくつかの測定が実行され、結果は次のとおりです。
-()〜39秒保存
-saveCounters()〜23秒
つまり saveCountersは最大41%高速です!
それで、秘密は何ですか?
すべてが非常にシンプルであることが判明しました。 saveCounterメソッドのコードは単純ですが、それはポイントではありません。 主なことは、これらのメソッドからのSQLクエリの内容です。
save()メソッドは、テーブル内のすべてのフィールドを含む重いクエリを生成します。
このようなもの:
UPDATE `banners` SET `id`=1, `name`='test', `info`='long-long description', `hits`=3560, `iduser`='2', `created_at`='2012-02-17 13:14:02', ... WHERE `banners`.`id`=1
saveCounters()メソッドは、この操作に最適なリクエストを生成します。
UPDATE `banners` SET `hits`=`hits`+1 WHERE `banners`.`id`=1
これがパフォーマンスの秘密です。
この情報があなたにとって有用であり、あなたのウェブアプリケーションが少し速くなることを願っています。