2012-03-30 51 views
0

私たちは、ユーザー向けの財務分析ツールである社内PHP Webアプリケーションを用意しています。当社は顧客の財務情報を処理して、ローン返済能力を分析する。クラス内で複数のクエリを処理する最も良い方法は?

多くの数と比率を生成する関数を持つクラスを作成しました。これらを使用して、アプリケーション内の異なるページ全体に合計、比率などを表示します。関数の合計を使用して新しい合計と比率を生成する関数をたくさん用意しています。ここに例があります:

//Coverage Ratio 
public function CoverageRatio($hma) { 
    return div_check(($this->NetFarmIncome($hma) + $this->NetNonFarmIncome($hma) - $this->FamilyLivingExpenses() - $this->IncomeTaxes()), ($this->InterestPortionTermDebt($hma) + $this->PrincipalPortionTermDebt($hma))); 
} 

//Operating Expense Ratio 
public function OperatingExpenseRatio($hma) { 
    return div_check($this->FarmOperatingExpenses($hma), $this->GrossFarmIncome($hma)); 
} 

//Net Nonfarm Income 
public function NetNonfarmIncome($hma = null) { 
    $result = $this->db->query("SELECT ah.id, COALESCE(v1.h1, 0) - COALESCE(v2.h2, 0) AS h, COALESCE(v1.p1, 0) - COALESCE(v2.p2, 0) AS p, COALESCE(v1.a1, 0) - COALESCE(v2.a2, 0) AS a FROM analysis_history ah LEFT JOIN (SELECT analysis_id, ... GROUP BY analysis_id) AS v2 ON v2.analysis_id = ah.id WHERE ah.id = $this->analysisid"); 
    $row = $result->fetch_assoc(); 
    return $row['a']; 
} 

//Net Business Income 
public function NetBusinessIncome($hma = null) { 
    $result = $this->db->query("SELECT ah.id, COALESCE(v1.h1, 0) - COALESCE(v2.h2, 0) AS h, COALESCE(v1.p1, 0) - COALESCE(v2.p2, 0) AS p, COALESCE(v1.a1, 0) - COALESCE(v2.a2, 0) AS a FROM analysis_history ah LEFT JOIN (SELECT analysis_id, ... GROUP BY analysis_id) AS v2 ON v2.analysis_id = ah.id WHERE ah.id = $this->analysisid"); 
    $row = $result->fetch_assoc(); 
    return $row['a']; 
} 

昨年、多くの変更が加えられ、新しい合計と比率を追加する必要がありました。ページの読み込み時間を生成し、実行されたクエリの数をカウントするようにアプリケーションを修正した後、私たちはショックを受けました。最大のページは生成に8秒かかり、122のクエリがあります。

クエリの数を減らすために調整を加えましたが、合計で約10個のクエリしか削除できませんでした。私たちの平均的なページには、約35件の検索クエリがあり、あまりにも多くの検索クエリしかありません。

解析ロジックを保持している私たちのクラスでは、複数の関数からデータを取り出して(そしてデータベースへの呼び出しを複数回行う)関数を変更して、単一のクエリを実行させるだけですか?私のCoverageRatioの例では、実際にはすべての関数がデータベースに6つのクエリを照会します。

コードを最適化する最良の方法はどれですか?それはうまくいくのですか?変更を行う必要がある場合に備えて、このようにするのが好きです。特定の合計を生成する関数を変更するだけです。純利益計算を使用する14以上の関数を管理しなければならないのは悪夢になります。純利益の計算方法を変更しなければならない場合、その値に依存するすべての関数のすべてのクエリを変更する必要があります。ご協力いただきありがとうございます!

+2

データベースの最適化も検討しましたか?適切なキャッシングと索引付けが適切な表構造の上にあることを確認することで、世界全体を変えることができます。 – BenOfTheNorth

答えて

3

同じテーブルセットから複数のものを計算する場合は、計算ごとに別々のSELECTステートメントではなく、別々の列にすべての計算を行う単一のSELECTステートメントで行う方が効率的です。

一時テーブルを使用して複数の他のクエリで必要な中間結果を保持し、それらを使用する各クエリの値を再計算しないようにすることで、パフォーマンスを向上させることもできます。

クエリに多数の結合が必要な場合は、EXPLAINを使用してデータベースでこれらの結合がどのように実行されているかを調べ、結合を効率的にするために追加できるインデックスがあるかどうかを調べます。よく選択されたいくつかのインデックスが大きな違いを生むかもしれません。

+0

さて、私はそれをやっていると考えていました。いくつかの関数で使用されるいくつかの総計計算(総資産、負債など)があります - 私は、すべてのページの負荷でそれらを計算することを考えていました。これはより効率的でしょうか? はい、複数の計算が同じ約10個のテーブルから行われています。クエリアナライザを幅広く使用して、クエリが最適化されているかどうかを確認します。 – Jeff

+0

数回ではなく1回行うことができるのは、プロセスから保存されるクエリの一部だけであっても、常に効率的です。 – BenOfTheNorth

関連する問題