Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 为什么此查询的参数化版本比非参数化版本运行得慢?_Sql_Sql Server_Sql Server 2005_Tsql_Sql Server 2008 - Fatal编程技术网

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生成的查询中。