2012-08-30 160 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); 
    } 
}