1

管理されたホストで centOS を実行している古いサーバーから、AWS で Ubuntu を実行している新しいサーバーに移動しました。

アイテムのリストをロードするページのレンダリングに 10 ~ 12 秒 (場合によっては最大 74 秒) かかっていることに気付きました。これは、古いサーバーではまったく気付かれませんでした。私は newrelic を使用して何がそんなに時間がかかっているのかを調べたところ、sfPHPView->render() に 99% の時間がかかっていることがわかりました。nerelic からは、ページをレンダリングするために DB に対して約 500 回の呼び出しが行われます。

このページはアイデアのリストで、各アイデアが行になっています。Doctrine 1.2 の $idea->getAccounts()->getSlug() 機能を使用します。アカウントは、対外関係としてのアイデアにリンクされた別のテーブルです。これは、アイデア行ごとに数回呼び出されます。各行要素のコードを保持するためにパーシャルは現在使用されていません。

  1. 行要素にパーシャルを使用すると、パフォーマンス上の利点はありますか? (今のところ、コードの保守性の利点を無視しています)
  2. 外部リレーションを介して接続されたデータを参照するためのベスト プラクティスは何ですか? $idea->getAccounts()->getSlug() が呼び出されるたびに DB に呼び出しが行われることに驚いています。
  3. そうでなければ、sfPHPView->render() の実行が centOS よりも遅くなる ubuntu に明らかなことはありますか?
4

2 に答える 2

2

私はあなたに私の考えを与えます

  • 行要素にパーシャルを使用する場合、パーシャルによってキャッシングをアフィンできるため、キャッシュに入れるのがより簡単になります。

  • クエリを作成するときにリレーションを明示的に定義しないため、Doctrine はすべての要素をリレーションで水和しません。この時点で、ハイドレートしたいリレーションを手動で定義できます。次に、呼び出しで$idea->getAccounts()->getSlug()毎回新しいクエリが実行されるわけではありません。

$q = $this->createQuery();
$q->leftJoin('Idea.Account');
  • ポイント3についてはわかりません。

PS : ポイント 2 については、リレーションからの情報を (リスト ビューで) 表示したい場合に、admin gen で多くのクエリを実行するのが非常に一般的です。解決策は、データを取得するメソッドを定義することです。

generator.yml で:

list:
  table_method: retrieveForBackendList

アイデアテーブルで:

public function retrieveForBackendList(Doctrine_Query $q)
{
  $rootAlias = $q->getRootAlias();
  $q->leftJoin($rootAlias . '.Account');

  return $q;
}
于 2012-05-14T07:28:58.520 に答える
0

jOkの推奨事項に加えて、ページの読み込み速度を向上させるために他に何をしたかを追加します。

明示的な結合に加えて、私は次のことを行いました。

  1. DQLクエリオブジェクトを返すように切り替えられ、その後Doctrineに渡されましたpaginator
  2. 使用include_partial()からPHPに変更include()され、オブジェクトの作成時間が短縮されました。include_partial()
  3. DBからのデータをオブジェクトではなく配列としてハイドレートします
  4. DBでより多くのleftJoinsを実行することにより、いくつかのforeachループを削除しました
  5. 結果とクエリのキャッシュを使用して、DB呼び出しの数を減らしました
  6. ビューキャッシングを使用してPHPテンプレートの生成時間を短縮

興味深いことに、1から4を実行することで、5と6がより効果的で、実装が容易になりました。キャッシングに飛び込む前に、コードを改善するために言わなければならないことがあると思います。

于 2013-03-04T10:55:28.130 に答える