我有一個MVC網站,提供了來自SQL Server數據庫的分頁列表數據記錄。 UI允許用戶根據許多不同的標準過濾返回的數據,例如,電子郵件地址。以下是一段代碼:Linq to Sql和T-SQL性能差異
Stopwatch stopwatch = new Stopwatch();
var temp = SubscriberDB
.GetSubscribers(model.Filter, model.PagingInfo);
// Inspect SQL expression here
stopwatch.Start();
model.Subscribers = temp.ToList();
stopwatch.Stop(); // 9 seconds plus compared to < 1 second in Query Analyzer
當此代碼運行時,StopWatch顯示大約9秒的執行時間。如果我捕獲生成的SQL表達式(就在它使用.ToList()方法進行求值之前)並將'作爲SQL Server Management Studio中的查詢'切換爲'',執行時間會縮短到不到1秒。僅供參考這裏是生成的SQL表達式:
SELECT [t2].[SubscriberId], [t2].[Email], [t3].[Reference] AS [DataSet], [t4].[Reference] AS [DataSource], [t2].[Created]
FROM (
SELECT [t1].[SubscriberId], [t1].[SubscriberDataSetId], [t1].[SubscriberDataSourceId], [t1].[Email], [t1].[Created], [t1].[ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [t0].[Email], [t0].[SubscriberDataSetId]) AS [ROW_NUMBER], [t0].[SubscriberId], [t0].[SubscriberDataSetId], [t0].[SubscriberDataSourceId], [t0].[Email], [t0].[Created]
FROM [dbo].[inbox_Subscriber] AS [t0]
WHERE [t0].[Email] LIKE '%_EMAIL_ADDRESS_%'
) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN 0 + 1 AND 0 + 20
) AS [t2]
INNER JOIN [dbo].[inbox_SubscriberDataSet] AS [t3] ON [t3].[SubscriberDataSetId] = [t2].[SubscriberDataSetId]
INNER JOIN [dbo].[inbox_SubscriberDataSource] AS [t4] ON [t4].[SubscriberDataSourceId] = [t2].[SubscriberDataSourceId]
ORDER BY [t2].[ROW_NUMBER]
如果我刪除電子郵件過濾條款,則控制器的秒錶返回一個類似的響應時間在SQL Management Studio中查詢,小於1秒 - 所以我假設SQL管道的基本接口工作正常,問題在於對Linq表達式的評估。我還應該提到,這是一個相當大的數據庫,在訂戶表中具有1M以上的行數。
任何人都可以點亮爲什麼應該有這樣一個高(x10)的性能差異,以及如果有什麼可以做到解決這個問題?
這樣做的常見原因是:參數嗅探和不同的SET選項(ansi_nulls,...)。嘗試搜索它們。 – usr 2012-08-08 19:21:12
如果您正在運行SQL Express的非快速版本,請啓動SQL Profiler並查看是否唯一正在執行的查詢。它也可能讓你更深入地瞭解時間花在哪裏。 – Richard 2012-08-08 19:24:20
@Neilski - 你能顯示你的GetSubscribers方法嗎? – 2012-08-08 19:28:27