2011-10-24 23 views
5

我試圖使用SQL Server 2008R2從ADO.NET運行查詢。我正在使用CTE爲@Offset@Limit提供分頁和添加參數,這兩個參數都是整數。ADO.NET超時但在SSMS中正常工作

我建立了一個參數化查詢,取決於用戶輸入。最終的輸出是這樣的:

;WITH Results_CTE AS (
    SELECT ld.* , ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE 
    WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
OPTION (RECOMPILE) 

我使用了幾個類似的條款這就是爲什麼我有OPTION RECOMPILE。如果我宣佈通過SSMS的參數和運行,像這樣:

declare @postcode varchar(10) = 'SW1 1AA'; 
declare @Offset int = 0; 
declare @Limit int = 10; 

我得到一個非常快速的響應時間(小於1秒)。如果我使用ADO.NET進行嘗試,則需要花費很長時間。我已經試過這兩種添加參數:

cmd.Parameters.AddWithValue("@Offset", startRowIndex) // times out 
cmd.Parameters.AddWithValue("@Limit", limit) 

cmd.Parameters.Add(New SqlParameter("@Offset", SqlDbType.BigInt)) // also times out 
cmd.Parameters.Item("@Offset").Value = startRowIndex 
cmd.Parameters.Add(New SqlParameter("@Limit", SqlDbType.BigInt)) 
cmd.Parameters.Item("@Limit").Value = limit 

如果只有第一個查詢返回雖然幾排,我放下@Offset@Limit過濾,我得到一個體面的響應時間。有沒有辦法我可以加快這個使用分頁?

編輯:我傳入@postcode參數(這是通過這.NET字符串:

cmd.Parameters.AddWithValue("@Postcode", normalizedPostcode) 
+0

@close voter。這不是一個騙局。前面的問題是關於用變量而不是參數來解釋不同的行爲。 SQL Server對這兩者進行了不同的處理。 –

+0

你可以在'@ postcode'參數中顯示你傳遞的代碼嗎? –

+0

它絕對是SQL超時?有沒有可能它的超時試圖獲得連接(例如,因爲當你這樣做的時候你有很多連接打開)或者其他類似的東西? – Chris

回答

7

你的ADO.NET代碼傳遞的a different datatype一個比一個參數,你是測試在SSMS和你正在隱式轉換的問題。

不要使用

cmd.Parameters.AddWithValue("@postcode", normalizedPostcode) 

,因爲這樣會自動創建一個nvarchar參數,並且您將在執行計劃中獲得隱式轉換,這意味着不能使用索引。而是傳遞一個明確創建的varchar類型參數。

cmd.Parameters.Add("@postcode", SqlDbType.Varchar, 10) 
+0

優秀的提示。將.NET中的參數精確地調整爲DBType可以獲得或多或少的即時響應。 – Echilon

2

1)對於@postcode參數please specify the length

cmd.Parameters.Add("@postcode", SqlDbType.VarChar, 10).Value = str

2)重寫查詢:

;WITH Results_CTE AS (
    SELECT ld.Key_Field, ROW_NUMBER() OVER (ORDER BY Key_Field) AS RowNum 
    FROM list..List_Data ld 
    WHERE VALUE_2010 IS NOT NULL 
    AND Postcode LIKE @Postcode + '%' 
) SELECT * FROM Results_CTE a 
INNER JOIN list..List_Data b ON a.Key_Field = Key_Field 
WHERE RowNum > @Offset AND RowNum < @Offset + @Limit 
--OPTION (RECOMPILE) 

注1:我假定Key_FieldList_Data表的主鍵(羣集)。

注2:檢查您是否有VALUE_2010和Postcode字段的索引。如果你有SQL 2008+,那麼你可以創建一個篩選索引:

--UNIQUE if Postcode has unique values for VALUE_2010 IS NOT NULL 
CREATE [UNIQUE] INDEX aaa 
ON MySchema.List_Data (Postcode) 
WHERE VALUE_2010 IS NOT NULL 
+0

這似乎將速度提高了幾毫秒,但它有所不同。不能傷害好的措施。 – Echilon

相關問題