2017-09-26 54 views
2

當我想接下來的LINQ查詢,它是緩慢的(1.5秒):LINQ的慢而快的SQL

var rslt = (from t in context.Set<SUB_Transactions>() 
      where 
      t.UpdateDate > query.LastUpdate && 
      t.TransactionID > query.Index 
      select new 
      { 
       TransactionID = t.TransactionID 
      }).OrderBy(t => t.TransactionID).Take(query.Amount).ToList(); 

當轉換爲SQL,這個查詢是超級快(40毫秒):

SELECT TOP (300) 
    [Project1].[TransactionID] AS [TransactionID] 
    FROM (SELECT 
     [Extent1].[TransactionID] AS [TransactionID] 
     FROM [dbo].[SUB_Transactions] AS [Extent1] 
     WHERE ([Extent1].[UpdateDate] > @p__linq__0) AND ([Extent1].[TransactionID] > @p__linq__1) 
    ) AS [Project1] 
    ORDER BY [Project1].[TransactionID] ASC 

這是怎麼回事?

除去第一查詢Take給出了一個快速的結果,以及(給出的快,有沒有新的交易)

上有TransactionIDUpdateDate一個綜合指數。

+0

問題編輯。我只是做一個.ToList()。 – Wouter

+0

僅從查詢優化的角度來看,您應該在日期之前首先搜索ID(假設結果在較小的結果集中)。日期不平等搜索相對耗時。如果LINQ語句很耗時,可能是因爲除了查詢轉換之外,它還會調用導航屬性,並且包含在後續文章中 – DiskJunky

+1

您是否可以將選擇部分轉換爲'select t.TransactionID',以便您不創建匿名對象爲單個屬性?一旦收到數據,這會使轉換速度更快 –

回答

3

至於你的榜樣去,這樣可以使你的查詢速度更快,但如果沒有一些樣本數據是不可能的,從我們的最終測試:

var rslt = (from t in context.Set<SUB_Transactions>() 
      where t.TransactionID > query.Index // invert order of filter 
       && t.UpdateDate > query.LastUpdate 
      order by t.TransactionID // you can orderby here 
      select t.TransactionID) // remove anonymous object 
      .Take(query.Amount) 
      .AsNoTracking() // you won't be changing IDs so no need to track them 
      .ToList(); 

你也可能獲得一些性能,如果你使用的DbSet<SUB_Transactions>代替致電Set<SUB_Transactions>()需要找到DbSetDbContext

+0

問題解決。過濾器的順序似乎對linq很重要,但對於SQL而言則很重要。其他的東西沒有明顯的區別。 – Wouter

+0

@Wouter您可以看到兩者的結果SQL併發布差異 –

+1

@CamiloTerevinto,Linq是程序性的,而SQL是聲明性的,優化程序正在執行大部分優化工作。這就是爲什麼謂詞順序在Linq中很重要,但不是SQL。 –