2012-08-08 118 views
1

我有一個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)的性能差異,以及如果有什麼可以做到解決這個問題?

+0

這樣做的常見原因是:參數嗅探和不同的SET選項(ansi_nulls,...)。嘗試搜索它們。 – usr 2012-08-08 19:21:12

+0

如果您正在運行SQL Express的非快速版本,請啓動SQL Profiler並查看是否唯一正在執行的查詢。它也可能讓你更深入地瞭解時間花在哪裏。 – Richard 2012-08-08 19:24:20

+0

@Neilski - 你能顯示你的GetSubscribers方法嗎? – 2012-08-08 19:28:27

回答

1

對此不太確定。 1M行與完全像可以採取安靜的時間。電子郵件索引?你可以使用Email%而不是%Email%運行查詢並查看會發生什麼?

+0

這個問題不是缺少索引或這樣的事情。問題在於相同查詢的持續時間不一致。它應該總是很慢或者總是很快。 – usr 2012-08-08 19:22:11

+0

我試着改變查詢來運行電子郵件%和Web UI的性能,並減少到與SQL Server Management Studio大致相同。從邏輯上可以看出,這種格式的查詢可以使用電子郵件索引,而%Email%不能這樣做,但這並不能解釋爲什麼SQL Server Management Studio中的性能好得多 - 出乎意料地如你所期望的那樣將不得不運行完整的記錄掃描。 – Neilski 2012-08-09 04:58:37

+0

有一次(像一年一次),我有同樣的問題,即在Management Studio中的查詢速度比在代碼中使用的快得多。也許Management Studio以某種方式優化它(它只是一個猜測)。 – gsharp 2012-08-10 05:29:12