ActiveRecord vs DAO-メモリ消費とクエリ速度のテスト

プロジェクト「 AutoOffice-Payment Acceptance and Full Automation of Sales 」の成長と開発の過程で、大量のメールニュースレターを作成および送信する主な機能の1つである100,000以上の連絡先を持つ顧客がデータベースに表示されるという事実に直面しましたこれらのオンラインストアの顧客のデータベースは恥知らずに減速し始めました。



コードを調べてみると、ActiveRecordクラスを使用してMySQLテーブルから合計100,000件以上のレコードをフェッチすると、メモリ消費とスクリプト実行時間が大幅に増加することが明らかになりました。 100,000レコードのサンプルの結果を含む1つの変数が644,750,972バイト(614 MB)のRAMを消費し、スクリプトの実行時間が50秒を超えるようになりました。



なぜなら 控えめに言っても、100,000エントリは究極の夢ではありません。AutoOfficeサービスの顧客数は長い間数千人にのぼりました。この問題を放置せずに解消するための措置を講じることはできませんでした。 その結果、上記の関数は、よく知られているDAOを使用してサンプルに完全に書き換えられ、リソース消費が大幅に削減され、スクリプトの実行速度が向上しました。



移行中、プログラマーは怠tooではなく、MySQLデータベース1、5、10、50、100、500、1,000、5,000、10,000、50,000、および5から取得しようとするときにActiveRecordとDAOを使用する比較特性を明確に示すいくつかのテストを行いました。 100,000エントリ。 これらのテストの結果から、今すぐ慣れることをお勧めします。



プロジェクトで同様のテストを実行する場合、数値がわずかに異なる場合があるため、すぐに予約します。 使用しているコンピューターの容量、データベースから選択したデータ、使用するインジケーターの測定方法についてはわかりません。



私の場合、標準のPHP関数を使用して、RAMの消費量を測定し、スクリプトの実行時間を計算しました。





この記事の目的は、ActiveRecordとDAOを使用する場合に、消費されるリソースの量の変化のダイナミクスとスクリプトの実行に費やされる時間を示すことです。



そのため、まずは、MySQLを使用してデータベースにアクセスするスクリプトのリソース消費と実行時間の増加を示すピボットテーブル:





この表では、ランタイムが0秒であることを理解することが重要です。 データの受信と結果の変数への保存に1秒未満費やされたことを意味します。

次に、MySQLデータベースからのデータで返される行の数の増加に応じて、RAM消費の増加のダイナミクスを見てみましょう。







グラフからわかるように、両方のアプローチを使用する場合、選択結果に1,000行を超える行が含まれる場合にのみ、大きな変化が始まります。 ただし、DAOを使用する場合のメモリ消費のインジケータは、ActiveRecordを使用する場合よりもはるかに低くなります。 そして、ピークパフォーマンスでは、DAOはActiveRecordの5.91倍少ないリソースを消費します。



もちろん、一部の「専門家」は、鉄(物理およびRAM)のコストが継続的に減少し、利用可能な最大サーバー容量が継続的に増加するため、鉄を追加購入するだけでこの問題を解決できると言うかもしれません。 しかし、リソース消費の増加のダイナミクスを見ると、1,000レコードから開始すると、リソース消費の増加はほぼ線形になります。 100,000レコードが614 MBを消費する場合。 控えめな見積もりによると、RAM、その後1,000,000レコードには6,140 MBが必要です。 (6 GB。)



次に、データベースクエリを満たす返された行の数に対するスクリプトの実行時間の依存関係を見てみましょう。







ここでは、すべてがすでにはるかに興味深いものです!



DAOを使用するときに返される値の数は、スクリプトの実行時間に実質的に影響しません。 テストのすべての段階で、この指標は1秒を超えませんでした。



ただし、ActiveRecordはリソースの消費とほぼ同じように動作しました。 MySQLデータベースから100,000件のレコードの結果を取得するのに52秒かかりましたが、これは深刻なインターネットプロジェクトではまったく受け入れられません。 インターネットリソースの正気なユーザーは、必要な情報がページに読み込まれるのを待つことはありません(もちろん、あなたがニッチの独占者でない限り)。



その結果、次のように言いたいです。



私はActiveRecordでの作業を本当に楽しんでいます。 大量のデータを取得する必要がないタスクのグループ全体を解決するのに便利で非常に適しています。 ただし、大量のデータを使用している場合、クエリで1,000レコード以上を返す必要がある場合は、すぐに別の何かを使用してクエリを作成し、サンプルの結果を取得することをお勧めします。たとえば、お気に入りのDAOやもっとクールなソリューションです。



私に質問がある場合、またはMySQLデータベースから大規模な選択を行った経験を共有したい場合は、コメントを書いてください。貴重なコンテンツに非常に感謝します。



All Articles