通過大量一對多映射提高查詢性能

dapper entity-framework petapoco sql-server

我正在使用Entity Framework到SQL Azure,在我的應用程序的一個頁面中,我們向用戶顯示了相當多的相關數據。我們在頁面上最多加載30個項目,但每個項目與其他對像有5個一對多映射。查詢時間處於合理的水平,但我在對象映射上洩漏了相當多的性能。 (差不多一秒鐘)。

這是我的對象的樣子的一個例子

public class Task
{
    public string Name {get; set;}
    public string Status {get; set;}
    public DateTime DueDate {get; set;}
    public IEnumerable<TaskData> Data {get; set;}
    public IEnumerable<Transaction> Transactions {get; set;}
    public IEnumerable<File> Files {get; set;}
    public IEnumerable<Comment> Comments {get; set;}
    public IEnumerable<People> People {get; set;}
}

任務具有名稱,狀態和截止日期。它還有許多 TaskData,它們是自定義名稱/值對, 許多顯示任務歷史的事務, 許多文件, 許多註釋和許多處理它的人員。

我的EF查詢看起來像這樣。

var Items = context.Items.Include(x=>x.Data).Include(x=>x.Files).Include(x=>x.Comments).Include(x=>x.People).Where(some constraint).ToList();

特定任務的相關性首先取決於狀態,然後是截止日期。所以我創建了一個IComparable覆蓋來與sort一起使用。關鍵是分頁查詢在這種情況下不能很好地工作,因為排序不是基於int或日期(我是對的嗎?)

在我們的其他應用程序中,我們顯示的每個任務的信息較少,Linq2Entities工作得很好。在這種情況下,對象映射正在殺死我們。我已經走上了與Dapper直接進入數據庫的道路,但是一對多的映射有它的警告。對於一些關係,我認為它會很好但不適合5-6。我接下來要看的是PetaPoco,但是在我認為我最好先把問題放在這里之前我沒有走得太遠。

我是否因為試圖帶回這麼多數據而瘋狂?有什麼方法可以獲得最大的性能?因為它只是應用程序的一個區域,所以我會稍微複雜一些。

一般承認的答案

我願意打賭你的EF查詢正在撤回過多的數據。問題是,“最佳”檢索技術在很大程度上取決於所拉取數據的類型和數量。

預先知道您可以根據預期的數據集調整運行的查詢。

例如......如果你只是拉動有限數量的具有大量子實體的實體,我在這裡寫的模式效果很好:

如何使用Dapper映射嵌套對象的列表

如果你知道你正在拉動哪些ID並且數量少於2000,你可以通過查詢單個網格和使用QueryMultiple映射來QueryMultiple例如:

cnn.QueryMultiple(@"select * from Tasks where Id in @ids 
select * from Files where TaskId in @ids
.. etc ..", new {ids = new int[] {1,2,3}});

如果您要更大的集合,則可能需要批處理,或者分階段進行批處理。


對於您的特定示例,我將查詢Tasks以獲取所有任務ID和數據,然後使用單個QueryMultiple將關係QueryMultiple到所有關聯表。



許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因