2011-06-30 29 views
2

我對Linq的工作原理並不瞭解。我剛剛嘗試了Linq的一些例子,這就是爲什麼我不確定並提出了問題。正在使用Linq和存儲過程比使用生成SQL的Linq執行得更好嗎?

一般來說,網絡上的Linq速度很慢。我的問題是,具有SP的Linq與使用生成的SQL的Linq相比具有更好的性能嗎?或兩者相同。

請指導。

+0

這取決於,執行的SQL命令是一樣的嗎? –

回答

7

因爲LINQ到SQL使用一QueryProvider即轉化Expression s到SQL語句,它必須由該供應商執行的每個查詢都這樣做(除非查詢預編譯[更多再在其上下來])。所以,例如在基本層面:

var people = context.People.Where(p => p.Name == "Matt"); 

LINQ到SQL語句需要表達p => p.Name == "Matt"轉換成表達式樹,它反過來又一個類似於轉換爲SQL語句,以:

SELECT t0.Name FROM People t0 WHERE t0.Name = 'Matt' 

對Sql Server執行查詢時,該查詢又需要爲該查詢生成執行計劃並對該表運行以獲取結果。爲正確的作業創建正確的查詢非常高效,並且支持更多的特殊數據查詢方法。

使用存儲過程,Linq-to-Sql不必生成表達式樹並從中生成sql,而是設計器生成的類具有所有需要將方法中的參數傳遞給存儲器的信息程序。

從這個意義上講,它更有效地使用存儲過程,但是你失去了執行這些常常有用的特殊查詢的能力。

您可能會發現它確實歸結爲在數據庫中使用sprocs與直接查詢的偏好(與您的DBA討論此問題)。

編譯查詢允許您使用預編譯語句的好處(該查詢只生成一次),因此後續查詢將使用先前編譯的查詢。一個例子是:

public IQueryable<Product> GetProduct(int id) 
{ 
    // Normal query, expression tree and sql generated each time it is 
    // it is executed against the data source. 
    return context.Products.Where(p => p.Id == id); 
} 

而一個編譯的查詢:

private static readonly Func<DataContext, int, IQueryable<Product>> ProductById = 
    CompiledQuery.Compile((context, id) => 
     context.Products.Where(p => p.Id == id)); 

public IQueryable<Product> GetProduct(int id) 
{ 
    return ProductById(context, id); 
} 

後者將使用預編譯查詢,因此它僅產生一次表達式樹和SQL。

1

當然,這一切都取決於您的查詢和您需要獲取的數據量。

查詢得到的越複雜,LINQ生成的SQL效率越低。

因此,如果您的查詢非常複雜/繁重,我建議您使用存儲過程/視圖,因爲那樣您將使用DB服務器的強大功能,而不是使用由LINQ2SQL生成的效率較低的SQL。