2010-12-09 80 views
4

我有一個LINQ查詢從基於一個ID列(其中id = @ ID)LINQ VS SQL(或.NET應用程式與SQL Server Management Studio中)

此查詢需要4秒視圖中檢索行跑。我已經使用SQL Server Profiler來檢查由linq執行的查詢,並且如果我將該查詢直接複製到management studio並執行,查詢只需要56ms。

這個指數時間增加在我的應用程序中的所有linq查詢中都是一致的。當(WPF)應用程序中執行< 100ms時,可能會導致執行時間延長?

== ==編輯

我已經成功地進一步孤立,言論表明探查持續時間;

/* 3953ms, 111487 reads */ 
context.SkuView.Where(p => p.TermId == 35 && !p.IsDeleted).ToList(); 

/* 90ms, 173 reads */ 
context.SkuView.Where(p => p.TermId == 35).ToList(); 

如果我把(sql呈現的)linq查詢直接粘貼到我得到的ssms中;

/* 250ms, 173 reads */ 
SELECT * FROM SkuView WHERE TermId == 35 AND IsDeleted = 0 

/* 250ms, 173 reads */ 
SELECT * FROM SkuView WHERE TermId == 35 

所以,問題有事情做與讀取使用p.IsDeleted時通過LINQ算...

+0

哇,這是一個巨大的時間差。要清楚,運行4秒是根據SQL事件探查器執行查詢所花費的時間? – Pandincus 2010-12-09 01:05:48

+0

正確。 linq使用exec sp_executesql執行查詢,Profiler顯示4秒的運行時間。如果我複製剛纔運行的確切的exec _sp_executesql,並在SSMS中執行它,profiler顯示58ms – 2010-12-09 01:12:57

+0

L2S不是查詢數據庫的最有效的方式,但這是一個非常大的差異。 – Phill 2010-12-09 01:17:19

回答

7

可能的罪魁禍首是:

  • 爭。當從Linq運行時,其他應用程序活動正在鎖定行並導致查詢停止等待鎖定。當從SSMS運行時,沒有其他活動,因此查詢速度快。
  • 參數類型的差異。將NVARCHAR參數傳遞給VARCHAR列進行比較會導致全面掃描(由於Data Type Precedence規則,索引無法使用)。這是由錯誤的LINQ ColumnAttribute造成的。當從SSMS運行時,查詢通常會不經意地被複制,並且參數類型被更改爲VARCHAR。
  • 冷跑與溫跑。查詢首先由LINq運行,這會加熱緩存(將數據從磁盤提取到內存)。當從SSMS再次運行時,不需要等待IO。

在任何情況下,調查工具都在您的處置。

  • 比較的數量從兩個查詢(RPC:Complete,在探查TSQL:BatchComplete事件)
  • 比較計劃讀取。使用Showplan XML事件。
  • 看看什麼是LINQ查詢sys.dm_exec_requests wait_type,WAIT_TIME和wait_resource列
  • 比較了兩種情況下的查詢統計:sys.dm_exec_query_stats。在logical_reads和physical_reads這兩種情況之間尋找的東西差異巨大,表明了非常不同的計劃(掃描vs.搜索),或者elapsed_time和worker_time(可能表示阻塞,鎖定的可能性)之間的差異。
0

這個查詢需要4秒,運行...如果我直接複製查詢管理工作室和執行,查詢只需要56MS。

您的應用程序和管理工作室之間沒有什麼神奇的區別。這兩個程序都創建了一個到數據庫的連接,併發出sql文本命令(一旦在數據庫服務器中:生成查詢計劃,IO和CPU被使用並且結果被傳回)。由於這裏唯一的區別是「應用程序建立連接」,所以您應該檢查連接。從連接字符串開始...

假設連接字符串中沒有問題,請轉到SET settings。特別是SET ANSI_NULLS應該打開,因爲它可能會干擾具有聚簇索引的計算列和視圖。

2

更新數據庫的統計數據解決了這個問題。

exec sp_updatestats 

大部分由於Remus用於學習;)

0

ARITHABORT是ON通過SSMS和OFF缺省默認爲一個SqlClient連接。

這解決了類似的問題,對我來說:

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery(); 
相關問題