7

主要問題 有一些已知的限制,天翻地覆,配置問題,任何東西,這可以解釋的事實,所有的事情都是平等的,從C#LINQ查詢運行可以採取訂單比以任何其他方式運行時間要長嗎?LINQ查詢非常緩慢相比,SSMS

這裏是linq中的縮寫查詢。它是視圖和表格之間非常直接的連接。

var query = (
    from content in context.ApprovedContentView 
       where content.BucketId == 13098 && content.ContentTypeId == 5220 
    join item in context.ActiveContent 
       on content.ContentId equals item.ItemId 
     where 
       item.IsSuchAndSuch == true && item.SomeOtherProperty == 5000 
     select new 
     { 
      ItemId = item.ItemId, 
      Title = item.Title, 
      SubTitle = item.SubTitle, 
      DescriptionText = item.DescriptionText, 
      /* about 10 other scalar fields */ 

     }); 

int count = query.Count(); 
var data = query.OrderByDescending(item => item.ItemId).Skip(5).Take(3); 

這裏是(略/ formmatted)SQL它產生

SELECT 
[GroupBy1].[A1] AS [C1] 
FROM (SELECT 
    COUNT(1) AS [A1] 
    FROM  [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
    (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [GroupBy1] 
GO 

SELECT TOP (3) 
[Filter1].[BucketId] AS [BucketId], 
[Filter1].[ItemId] AS [ItemId], 
[Filter1].[Title] AS [Title], 
[Filter1].[SubTitle] AS [SubTitle], 
[Filter1].[DescriptionText] AS [DescriptionText], 
/* other fields */ 
FROM (SELECT 
      [Extent1].[BucketId] AS [BucketId], 
      [Extent2].[ItemId] AS [ItemId], 
      [Extent2].[Title] AS [Title], 
      [Extent2].[SubTitle] AS [SubTitle], 
      [Extent2].[DescriptionText] AS [DescriptionText], 
      /* other fields */ 
      row_number() OVER (ORDER BY [Extent2].[DealId] DESC) AS [row_number] 
    FROM [SchemaX].[ApprovedContentView] AS [Extent1] 
    INNER JOIN [SchemaX].[ActiveContent] AS [Extent2] ON [Extent1].[ContentId] = [Extent2].[ItemId] 
    WHERE (13098 = [Extent1].[BucketId]) AND (5220 = [Extent1].[ContentTypeId ]) AND 
      (1 = [Extent2].[IsSuchAndSuch]) AND (5000 = [Extent2].[SomeOtherProperty ]) 
) AS [Filter1] 
WHERE [Filter1].[row_number] > 5 
ORDER BY [Filter1].[DealId] DESC 

不同的場景 我正在立足於觀察查詢我的速度測試運行使用SQL事件探查

原位 當這個linq查詢在我的c#應用程序中作爲其正常操作的一部分執行時,我觀察到在sql分析器中,select count需要3秒鐘完成c完成,奇怪的是,產生投影的查詢只需要200毫秒,並且時間是可重複的,這似乎排除了查詢執行計劃緩存問題。

IN LINQPAD (與實體框架5,SQL Server 2008 R2中運行),當我執行通過LinqPad的LINQ語句,使用C#應用程序的DLL的數據上下文,計數和投影每完成一個季度下秒(約224ms,每個總運行時間約450ms)。

SSMS中 不管SQL的來源,當我複製SQL配置文件報告其執行並粘貼到一個管理工作室窗口,執行實際的代碼,它需要大約224ms。

數據庫優化 在SSMS,當我評價,我複製從分析器(無論是從代碼或從linqpad)的SQL實際執行計劃,我發現SQL是使用所有正確的索引,並報告只有索引尋求 - 沒有表掃描,沒有擺脫查找。

那麼,什麼給了?有人見過這樣的事嗎?

+0

也許你有一個緩存的執行計劃,該計劃已經過時?可能會解釋爲什麼只有當你從應用中找到它時纔會看到它。 – FlyingStreudel 2013-03-11 16:36:42

+0

它返回多少行?這是您的應用程序的第一個查詢嗎? – ken2k 2013-03-11 16:37:44

回答

5

我會確保您沒有爲您的應用程序緩存的錯誤執行計劃。我經常在對已經使用的數據庫進行模式工作時發生這種情況。有可能您的執行計劃已針對您的應用程序執行上下文緩存,由於架構更改而效率低下,而爲您的SSMS查詢生成的執行計劃是最新的並且沒有看到這些性能問題。

我會嘗試使用DBCC FREEPROCCACHE來強制更新您的執行計劃並查看是否可以解決問題。

+0

這看起來已經打破了日誌堵塞。謝謝!! – groggyjava 2013-03-11 18:22:56

+0

這對我有效。對我的本地數據庫運行一個相同的查詢一直在EF中持續44秒。我在profiler中捕獲了查詢,並在SSMS中運行它,並且在不到1秒的時間內完成。我在兩者之間來回切換,在兩者中運行相同的查詢,並且這些令人滿意的運行時間差異是一致的。在運行DBCC FREEPROCCACHE之後,兩個查詢都在1秒內運行。 – Triynko 2016-07-08 17:39:37

0

ARITHABORT SSMS默認爲ON,SqlClient連接默認爲OFF。

如果問題顯示出來再次添加:

new SqlCommand("SET ARITHABORT ON", connection).ExecuteNonQuery();