1

Postsとを含む Web ページを作成していますComments。ただし、そのレンダリング中にCommentsfor eachを取得すると、取得が非常に遅くなります。私の推測では、これは接続を頻繁に開いたり閉じたりすることが原因であると思われます。とにかく、それはうまくスケーリングしません。PostPost

これを修正するために、2 つのエンティティを 1 つにマージし、モデリングPostsCommentsポリモーフィスな方法を検討しています。つまり、Entryは と によってサブクラス化されたスーパークラスにPostなりCommentます。

これが有効なアプローチであるかどうかについて、誰かアドバイスをもらえますか? あるいは、私が考えもしなかったネストされたRepeater/DataListパフォーマンスの問題も解決する可能性のある他の提案を受け入れます。

4

2 に答える 2

1

投稿に何千ものコメントがあるブログを持っていたとしても、それはうまく機能します.
RDBMS テーブルは、何百万ものレコードになることがよくあります。

接続を頻繁に開いたり閉じたりすると、パフォーマンスのボトルネックになります。
すべてのデータを一度に取得してから、ネストされたリピーターに渡す必要があります。

于 2012-08-30T04:00:11.687 に答える
1

nunespascal が言ったことを拡張するには:

2 つの別個のテーブルを介して 2 つの別個のエンティティとしてデータを引き戻す場合でも、同じテーブルから多態的にデータを引き戻す場合でも、問題はデータの要求方法にあるようです。

C# 風の EF 擬似コードで次の 2 つのアプローチを検討してください。

アプローチ 1: 子を繰り返しロードする

var posts = db.Posts;
foreach (Post p in posts) {
    Html.Render(p);

    var comments = db.Comments.Where(c => c.PostId == p.PostId);
    foreach (Comment c in comments) {
        Html.Render(c);
    }
}

これは、現在のリピーター反復で本質的に行っているように聞こえることです。投稿ごとに、それに属するコメントを読み込み、レンダリングします。

これにより、説明したボトルネックが正確に作成され、多くの接続を開いたり閉じたりして、多くの個別のアトミック SQL ステートメントを実行します。可能であればこれを避けてください。

アプローチ 2: 親と子を一緒にロードする

var posts = db.Posts.Top(10);
// ^ The .Top(10) limits the result-set to a manageable number of posts (10).

var ids = posts.Select(p => p.PostId);
// ^ This line creates an Enumerable list of the IDs of your loaded posts.

var comments = db.Comments.Where(c => ids.Contains(c.PostId));
// ^ This line loads all the comments which belong to the 10 posts you loaded.

foreach (Post p in posts) {
    Html.Render(p);

    foreach (Comment c in comments.Where(c => c.PostId == p.PostId)) {
        // This loop iterates the comments in the same way the previous example
        // showed, with the exception that it iterates *in memory*, rather than
        // running additional SQL on each iteration.
        Html.Render(c);
    }
}

2 番目の例ではすべてのアイテムをメモリにロードしているため、すべてのラウンド トリップを節約できます。作成する SQL ステートメントは 2 つだけで、どちらも最初に実行されます。

実際に EF4/5 (上記のコードが基づいている) を使用している場合は、実際には次のこともできます。

var posts = db.Posts.Include("Comments");
// ^ This line loads both Posts and Comments in a single SQL statement

foreach (Post p in posts) {
    Html.Render(p);

    foreach (Comment c in p.Comments) {
        // EF5 and other ORMs can create a .Comments property which contains an
        // Enumerable list of the comments, already filtered on the FK binding
        Html.Render(c);
    }
}
于 2013-04-18T17:41:11.743 に答える