簡體   English   中英

如何解決實體框架中的緩慢聯接查詢

[英]How to work around slow joining queries in Entity Framework

我有一個MVC 4項目,該項目正在使用Code First和Entity Framework 6(由SQL Server 2008支持)。 我正在嘗試優化一個看起來像這樣的特別討厭的查詢:

var tops = Context.Top
    .Include(t => 
        t.Foo
            .Select(f => f.FooChild1
                .Select(c => c.Baz)))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild3))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild2))
    .Include(t =>
        t.Foo
            .Select(f => f.FooChild1
                .Select(c => c.Bar)))
    .Where(t => t.Foo.Count > 0)
    .ToList();

關系如下所示:

Top  
    1 ----> 0..N  Foo
        1 ----> 0..N  FooChild1
            1 ----> 0..N Bar
            1 ----> 0..N Baz
        1 ----> 0..N FooChild2
        0..N ----> 1 FooChild3

如您所見,該查詢需要大量的加載,因此生成的查詢具有大量的聯接。 事實證明,對於我正在處理的結果數據,延遲加載太慢了。

在SQL Server上執行此查詢所生成的查詢大約需要2秒鍾,但是獲取我需要的數據的手寫查詢僅需要大約91毫秒。 有什么我可以做來改善的嗎?

我嘗試過的

我嘗試通過在需要的所有其他表上調用Load()並擺脫所有Include的方法來進行預加載。 我不確定為什么(也許這個技巧不適用於DbContext ),但是沒有效果。 導航屬性是延遲加載的。

我在考慮什么

  1. 我想到的一個選擇是手寫一個查詢所需數據的SQL視圖,並在Code First中將一個實體映射到該視圖。 不知道如何確切地做到這一點,但是我希望這樣做可以避免所生成查詢中的不良性能。

  2. 修改數據庫的設計,以便將我需要的信息緩存在Top表中。 我不喜歡此選項中的數據重復,但是至少我不必遍歷那么多的導航屬性。

有指針嗎?

您可以使用預編譯查詢來提高性能。 諸如此類(來自msdn的示例,原因是我不知道您的類型):

static readonly Func<AdventureWorksEntities, Decimal, IQueryable<SalesOrderHeader>> s_compiledQuery2 = 
    CompiledQuery.Compile<AdventureWorksEntities, Decimal, IQueryable<SalesOrderHeader>>(
            (ctx, total) => from order in ctx.SalesOrderHeaders
                            where order.TotalDue >= total
                            select order);

static void CompiledQuery2()
{            
    using (AdventureWorksEntities context = new AdventureWorksEntities())
    {
        Decimal totalDue = 200.00M;

        IQueryable<SalesOrderHeader> orders = s_compiledQuery2.Invoke(context, totalDue);

        foreach (SalesOrderHeader order in orders)
        {
            Console.WriteLine("ID: {0}  Order date: {1} Total due: {2}",
                order.SalesOrderID,
                order.OrderDate,
                order.TotalDue);
        }
    }            
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM