Sql 为什么此查询的参数化版本比非参数化版本运行得慢?
示例查询:Sql 为什么此查询的参数化版本比非参数化版本运行得慢?,sql,sql-server,sql-server-2005,tsql,sql-server-2008,Sql,Sql Server,Sql Server 2005,Tsql,Sql Server 2008,示例查询: CREATE PROCEDURE dbo.Test (@p varchar(10)) AS DECLARE @param varchar(10) SET @param = @p + '%' SELECT * FROM table1 t1 INNER JOIN table2 t2 on t1.id = tr.id WHERE t2.desc LIKE @param 我有一个类似于上面的查询,当我在存储过程中使用它时,它会无限期地运行,不会给出任何输出。但如果我使用与相同的查询 SE
CREATE PROCEDURE dbo.Test (@p varchar(10))
AS
DECLARE @param varchar(10)
SET @param = @p + '%'
SELECT * FROM table1 t1
INNER JOIN table2 t2 on t1.id = tr.id
WHERE t2.desc LIKE @param
我有一个类似于上面的查询,当我在存储过程中使用它时,它会无限期地运行,不会给出任何输出。但如果我使用与相同的查询
SELECT * FROM table1 t1
INNER JOIN table2 t2 on t1.id = tr.id
WHERE t2.desc LIKE 'A%' -- notice no parameter here
这将在不到一秒钟的时间内执行
我的表2有140K条记录,表1大约有250K条记录
知道什么会导致like运算符运行缓慢吗?它在编译时不知道
@param
不会有前导通配符,因此当它编译批时,它会给您一个带有扫描而不是搜索的计划
您可以尝试
选项(重新编译)
或选项(FORCESEEK)
(SQL Server 2008),看看它是否为您提供了一个更好的计划。您看过查询的解释计划吗?根据您的测试,它听起来与类似的关键字没有任何关系,因为即使是快速版本也包含该操作符。我尝试同时运行这两个操作符,当我直接使用参数时,它运行不到一秒。选项(重新编译)有效。现在它运行不到一秒钟。我原来的查询有4个内部联接和3个左外部联接。@rs-在做了一些测试之后,尽管我开始怀疑我的解释。当我查看存储过程计划时,我发现两者都以索引范围seek结束。参数化版本有一个计算标量运算符,它调用LikeRangeStart
和likerangend
。实际上,即使有前导通配符,它也会使用此范围搜索。你的执行计划是什么样的?我想知道排序是否会产生影响(或者可能只是一个扭曲统计的问题,意味着它会改变运算符的顺序),我也不认为这是原因。我看到了同样的行为。选项(重新编译)确实有帮助,但我无法将其注入EF生成的查询中。