ADO.NET超时但在SSMS中工作正常

时间:2011-10-24 11:58:10

标签: .net sql sql-server sql-server-2008 ado.net

我正在尝试使用SQL Server 2008R2从ADO.NET运行查询。我正在使用CTE为@Offset@Limit提供分页和添加参数,这两个参数都是整数。

我正在根据用户输入构建参数化查询。最终的结果如下:

;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)

2 个答案:

答案 0 :(得分:7)

您的ADO.NET代码传入的参数a different datatype比您在SSMS中测试的参数更多,并且您会收到隐式演员问题。

不要使用

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

因为这将自动创建nvarchar参数,您将在执行计划中获得隐式强制转换,这意味着无法使用索引。而是传递明确创建的varchar类型参数。

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

答案 1 :(得分: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和邮政编码字段的索引。如果您有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