2010-12-16 42 views
11

想知道,添加LINQ方法的順序是否重要?任何重要的LINQ方法的順序?

例如,

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .Where(u => u.UserName.StartsWith("t")) 
        .OrderByDescending(u => u.CreatedDate) 
        .FirstOrDefault(); 
} 

,這完全是一樣的嗎?

using(MyDataContext context = new MyDataContext()) 
{ 
    var user = context.Users 
        .OrderByDescending(u => u.CreatedDate) 
        .Where(u => u.UserName.StartsWith("t")) 
        .FirstOrDefault(); 
} 

當然,我可以讓所有的方法一個一個地測試,但我想對邏輯有一些總體的想法。

所以:

  • 除了像FirstOrDefault(),ToList()等方法方法,真正觸發執行是它的任何重要的是具有在LINQ聲明某種類型的訂單?

再次感謝!

+0

在這種情況下,我只是比較生成的查詢並手動在數據庫上執行它們以進一步分析執行計劃。 – 2010-12-16 08:36:27

回答

10

在LINQ to SQL中,我期望這兩個查詢是相同的 - 即使不是完全相同的SQL,它們也應該以相同的查詢計劃結束。

在LINQ to Objects中,它們的行爲會非常不同。想象一下,你有一百萬用戶,但其中只有兩個用戶名以「t」開頭。在第一種形式中,您需要過濾然後對這兩個用戶進行排序......在第二種形式中,它需要在開始過濾之前對的所有內容進行排序

當然,還有其他情況下,訂購也很重要 - 特別是,如果您有一個Select一半,然後Where子句,那麼您將過濾不同的事情。想象一下:

var query = Enumerable.Range(-20, 30) 
         .Select(x => -x) 
         .Where(x => x > 5); 

VS

var query = Enumerable.Range(-20, 30) 
         .Where(x => x > 5) 
         .Select(x => -x); 

在第一示例中的結果將是 「20,19,18,... 6」,而在所述第二查詢的結果將是「-6 ,-7,-8,-9,-10「。巨大的不同!

1

我不是100%確定的,但我認爲第二個比較慢,因爲您對一大組數據進行排序。如果您首先進行過濾,則會刪除一些元素,從而使分類更快。但是,結果應該是一樣的。

編輯:由於這看起來像linq-to-sql(如果您不使用另一個linq提供程序),它應該歸結爲在此示例中執行的相同查詢。但是有些情況下,linq-to-sql中的順序也很重要(參見Jon的例子)。然而,唯一能夠100%確定的方法是使用分析器來調查生成的sql查詢(但在這個例子中我不認爲有任何區別)。

+0

@Tomas:這是從LINQ到SQL,看起來它......我希望* *客戶端查詢生成*或*服務器端優化器發現。 – 2010-12-16 08:36:39

+0

@Jon:這是真的,對於LINQ到SQL,他們應該生成相同的SQL。我只考慮了linq部分,並沒有反映'DataContext'。這件事情是你不能確定,或者你可以嗎?唯一的方法是使用分析器來真正檢查生成的sql查詢。 – 2010-12-16 08:41:33

+0

@Tomas:在這種情況下我相當有信心 - 但我認爲這是一個好主意,看看你的LINQ產生什麼類型的查詢:) – 2010-12-16 08:43:09

0

它可能有性能問題。在你的情況下,第一個例子將是最好的,因爲在第二個例子中,你首先在過濾之前對整個列表進行排序。你甚至可以將所有不需要的東西分類,然後刪除不需要的部分。首先刪除所有你不需要的東西,然後你將排序(可能)要小得多的子集。

所以對於這個確切的查詢,結果是一樣的,但是對於一組大數據,第一個數據將是最快的一個。

+0

@Øyvind:根據我對其他答案的評論:這看起來像LINQ to SQL,其執行流程幾乎沒有LINQ to Objects那樣規定。我希望即使在大量數據上,它們也能夠等效執行 - 因爲SQL查詢優化器應該對它進行排序。 – 2010-12-16 08:38:11

+0

@Jon - 在回顧這個問題時,我同意你的看法,這看起來像LINQ to SQL,當然你是對的。然而,在LINQ to Objects上,差異將是至關重要的。 – 2010-12-16 08:52:09

1

一般來說,是的,它確實很重要。你可以得到不同的表現和/或不同的結果。

在您的具體示例中,訂單不會改變結果。對於大多數提供程序(如LINQ to SQL和LINQ to Entities),它們也不會有任何區別 - 將生成相同的SQL。

對於其他提供者,不同的順序可能會改變性能特徵,但它如何確實取決於特定的提供者。例如,我不認爲LINQ to Objects對於兩個查詢都會有相同的性能。

1

如何使用Sql Profiler?那會給出正確的答案。

4

這取決於您正在使用哪個LINQ提供程序。在LINQ to SQL的情況下,無論哪種情況,表達式樹都將解析爲相同的基礎SQL查詢。但是,對於不太聰明的提供者,您可能會發現先執行.Where()會更有效,因爲它會在對它們進行排序之前過濾對象,這可能會對大量實體產生不同影響。

1

我認爲這是關於LINQ到XXXX的提供者。誰寫的提供者可以說它可以做什麼(關於優化等)。即使在同一個LINQ提供者的另一個版本中,也可能給出不同的結果(只是在翻譯中)。

簡而言之,LINQ提供者只是翻譯者,所以你應該從現在使用的LINQ提供者的創建者那裏提出這個問題。