【发布时间】:2011-10-24 10:14:58
【问题描述】:
我有一个通过 ADO.NET 与 SQL Server 2008R2 一起使用的查询。当我使用内联 LIKE 子句时,它会在不到一秒的时间内工作,从 200 万返回 5 行。如果我像在 .NET 中那样在 SSMS 中的查询开始时声明参数,则需要很长时间。
这是同一个查询,但参数化了。
第一个(效果很好)是(效果很好):
;WITH Results_CTE AS (
SELECT ld.* , ROW_NUMBER() OVER (ORDER BY PK_ID) AS RowNum
FROM list..List_Data ld
WHERE Name IS NOT NULL AND
Postcode LIKE 'SW14 1xx%'
) SELECT * FROM Results_CTE
需要永远的第二个是:
declare @postcode varchar(10) = 'SW14 1xx'
;WITH Results_CTE AS (
SELECT ld.* , ROW_NUMBER() OVER (ORDER BY PK_ID) AS RowNum
FROM list..List_Data ld
WHERE Name IS NOT NULL AND
Postcode LIKE @postcode +'%'
) SELECT * FROM Results_CTE
我相信这与 SQL Server 的内部工作原理有关,但我真的不知道。
【问题讨论】:
-
在
like上搜索会使优化器不太可能使用索引。在第一种情况下,它可以看到字符串的开头没有通配符,因此它将使用索引。或许你可以hint表示应该使用索引。 -
@KlasLindbäck - SQL Server 将参数化的
LIKE实现为范围搜索,因此在它具有非前导通配符的情况下,查询不会受到惩罚(在存在前导通配符的情况下range 是整个索引)。大概在这种情况下,虽然Postcode上有一个非覆盖索引,但它没有使用它,因为它过度估计了需要的查找次数。 -
@Echilon:第二个查询的解释计划是什么?您可以尝试的一件事是在调用查询之前将“%”添加到
postcode(以防+ '%'混淆优化器)。应该没什么区别,但值得一试。 -
在处理 SQL Server 性能问题时,您应该始终get an execution plan
标签: sql sql-server sql-server-2008 ado.net parameterized