2011-03-25 117 views
10

查詢1:(快如閃電)爲什麼sp_executesql的參數時作爲參數傳遞運行速度較慢

sp_executesql "select * from tablesView where Id = 1" 

問題2:(太慢)

sp_executesql "select * from tablesView where Id = @Id", N"@Id int", @Id=1 

tablesView - a view containing multiple joins

LINQ總是將查詢轉換爲Query2表單,因此性能非常糟糕。

問題:我需要查詢2緩慢的原因,以及任何解決方案(如果有的話)。 併爲LINQ解析。

----附加註釋:

對性能的影響肯定是因爲2列,其使用排名函數(ROW_NUMBER),但我不能避免他們我需要他們。

+0

你有很多與ID = 1的行? – 2011-03-25 21:07:16

+0

@Lasse,即使我有50條記錄,差異是巨大的。比如0秒和10秒,有一點是select * from table,通常是一個有很多連接的視圖。 – WhoIsNinja 2011-03-25 21:08:43

+0

「@ id」傳入的數據類型是什麼?您可能會進行隱式轉換以防止使用索引。 – 2011-03-25 21:09:17

回答

0
  1. 避免使用SELECT *
  2. ADO.NET 3.5有 「參數quessing」 中的LINQ 1 = TINYINT 2345 = SMALLINT 76357242 = INT .. 在ADO.NET 4.0參數quessing替換默認INT數據類型1 = INT,2335 = INT,76357242 = INT)
+0

我從不使用select *,這僅僅是一個例子。 – WhoIsNinja 2011-03-25 21:22:58

7

我要去這裏走出去的肢體,並假定你有很多行的其中ID = 1

如果沒有,請糾正我。

一個可能的原因是SQL Server正在處理您的查詢速度慢是,它看起來在查詢和雲:

嗯,我不知道他會通過該參數。
它會是1嗎?在那裏我有關於gazillion行?
或者是1742,在那裏我有僅有3
我只是不知道,我最好做一個表掃描,以確保生產出將覆蓋所有我的基地

如果某列的執行計劃,或一個列集具有較低的選擇性(即,唯一值的數量遠遠小於行數),SQL Server有時會返回到表掃描或類似行爲,以便確定性地獲取所有行。

至少這是我的經驗。特別是我在執行日期範圍時選擇具有時間限制數據的表時會看到相同的行爲,請執行WHERE dt <= @dt AND dt >= @dt以獲取@dt在該行內一段時間內的所有行,然後恢復爲表掃描,並且那麼當我將實際日期作爲文字放入SQL中時,它運行的速度會更快。

這裏的問題是選擇性,SQL Server不知道如何最好地滿足所有場景時爲您的語句構建執行計劃,因此它會嘗試猜測。

嘗試添加查詢提示以指定參數的典型值,即。:

sp_executesql "select * from tablesView where Id = @Id option (optimize for (@id = 1742))", N"@Id int", @Id=1 
+0

優化並沒有幫助,但我不能要求linq在其構建的查詢中添加優化。 :( – WhoIsNinja 2011-03-25 21:31:20

+0

說到記錄,如果在這個查詢中沒有where子句,將會有100萬條記錄被返回,因爲這個視圖包含巨大的表之間的連接 – WhoIsNinja 2011-03-25 21:34:02

+1

1.誰對「沒有where子句」和「嘗試使用optimize for子句執行SQL並查看差異?3)...是不知道數據仍然是最佳方法的ORM? – 2011-03-25 21:41:36

2

這可能是一個參數嗅探問題。嘗試包括線路:

OPTION (RECOMPILE) 

在您的SQL查詢的結尾。

有文章在這裏解釋什麼參數嗅探是:http://blogs.technet.com/b/mdegre/archive/2012/03/19/what-is-parameter-sniffing.aspx

+0

儘管我不能直接使用它,但它是我的問題的答案,即參數導致表掃描而不是使用索引。使用OPTION(RECOMPILE)確實強制底層視圖使用使用表索引的計劃。不幸的是我無法使用這個,因爲我的SQL中間件解析器不能接受這個語法。我的解決方法是構建不帶參數的SQL,有效地將值編碼到查詢中。沒有理想,但它避免了將查詢轉換爲sp_executesql。 – Paul 2015-04-02 09:49:53