2012-08-30 111 views
1

我正在创建一个包含PostsComments的网页。然而,当我在Post的渲染过程中为每个Post检索Comments时,检索速度非常缓慢。我的猜测是,这是由于经常打开/关闭连接。无论如何,它不能很好地扩展。SQL和ASP.net中的层次结构

为了解决这个问题,我正在考虑将两个实体合并为一个,并以多形方式为PostsComments建模。换句话说,Entry成为一个超级类别,分为PostComment

任何人都可以给我一些建议,这是否是一种有效的方法?或者,我愿意接受其他建议,这些建议也可能解决我可能没有想到的嵌套性能问题。

+0

如果我的回答帮你,请考虑将其标记为“已接受”通过点击其下方的小复选框。如果没有,请让我知道你需要什么进一步的信息,所以我可以帮助你更多。 –

回答

1

即使您的博客上有数千条关于帖子的评论,它仍然会运行良好。
RDBMS表经常遇到数百万条记录。

打开和关闭连接经常会成为性能瓶颈。
您应该一次获取所有数据,然后将其传递给您的嵌套中继器。

1

要展开什么nunespascal说:

无论您是通过两个独立的表把数据回作为两个独立的实体,或者你拉回来多态了同桌的,这听起来像问题你正在附近如何你正在请求数据。

考虑C#-ish EF伪代码这两种方法:

方法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语句,两者都在开始时运行。

如果您在实际使用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); 
    } 
}