2011-04-15 51 views
0

我有一個正在通過LINQ to SQL執行的查詢。查詢如下所示:直接SQL查詢與EXEC

exec sp_executesql N' 
SELECT DISTINCT [t2].[ID],... 
FROM 
    Table1 AS [t0] 
    INNER JOIN Table2 AS [t1] ON [t0].[Table1ID] = [t1].[Table1ID] 
    INNER JOIN Table3 AS [t2] ON [t2].[Table2ID] = [t0].[Table2ID] 
WHERE 
    ([t2].[Visible] = @p0) 
    AND ([t1].[AncestorID] IN (@p1,...,@p277))',N'@p0 int,...,@p277 int',@p0=1,[email protected]=2875 

正如您所看到的,它基本上是一個帶有277個參數的子查詢。使用exec並傳遞參數如上,查詢需要20秒

如果我將查詢從exec調用中拉出並「正常」運行,則需要的時間少於,而不是一秒。下面是該查詢:

DECLARE @p0 int; 
... 
DECLARE @p277 int; 

SET @p0=1; 
... 
SET @p277=287; 

SELECT DISTINCT [t2].[ID],... 
    FROM 
     Table1 AS [t0] 
     INNER JOIN Table2 AS [t1] ON [t0].[Table1ID] = [t1].[Table1ID] 
     INNER JOIN Table3 AS [t2] ON [t2].[Table2ID] = [t0].[Table2ID] 
    WHERE 
     ([t2].[Visible] = @p0) 
     AND ([t1].[AncestorID] IN (@p1,...,@p277)) 

第三項測試,當我換一個exec裏面的第二個查詢,它工作瞬間依然。所以問題似乎是在exec調用中傳遞參數。

+0

我猜(隱含的)問題是,「我如何讓這個運行更快?」 – JNK 2011-04-15 18:28:55

+0

這與LINQ有什麼關係? – 2011-04-15 18:42:36

+0

第一個查詢是LINQ-to-SQL產生的。問題是「爲什麼這些查詢在覈心上是相同的,以不同的速度運行」。 – 2011-04-15 18:52:02

回答

0

問題很可能與「參數嗅探」和有關@Mikael會談鏈接的文章做。不幸的是,這是使用ORM的主要缺點之一,因爲你失去了調整SQL以提高性能的能力。

這裏有一些事情要嘗試:

  1. 運行DBCC FREEPROCCACHE並再次運行 查詢從應用看 如果有任何區別。運行 多次不會得到新的 執行計劃,因爲它已經從第一次運行緩存了 。
  2. 一定要重建的 表的索引,以確保該 統計數據是最新的(一個 重建,而不是碎片整理應該 自動更新數據)
  3. 如果需要的話,可以隨時轉換此 操作到存儲過程,並調用從LINQ到SQL的 。您可能會然後 不得不通過值的列表作爲逗號分隔列表或XML。如果您使用SQL Server 2008(或更新版本),最好的解決方案是 在應用程序端構建一個DataTable並將 作爲表值參數 傳入到Proc中,並在INNER JOIN中使用它,而不是在IN列表。

而且,你的第二個和第三個測試是基本相同的條件查詢都基於查詢的確切內容,包括空格等,所以它包裹在EXEC真的不應該一鍵緩存他們的計劃不會改變優化器看到它的方式。