像存储过程一样慢,像查询一样快 - 不是参数嗅探

Posted

技术标签:

【中文标题】像存储过程一样慢,像查询一样快 - 不是参数嗅探【英文标题】:Slow as a stored procedure, fast as a query - not parameter sniffing 【发布时间】:2013-08-21 07:18:09 【问题描述】:

我有一个困惑的问题。我有一个 SP,其中包含一个带有少量 JOIN 的查询(其中 2 个是 LEFT JOIN)。 SP 需要 10 秒,如果我将查询作为查询执行 - 需要 200 毫秒...

这不是参数嗅探问题:即使我清理缓存并仅使用一组参数执行 SP - 仍然很慢。 我还尝试通过重新编译来执行 SP,并在 SP 的查询中添加选项(重新编译) - 仍然很慢。

我试试这些链接:

Query runs fast, but runs slow in stored procedure SQL Server: Query fast, but slow from procedure Query times out when executed from web, but super-fast when executed from SSMS

我还要提一下:

    SP的2个参数是table类型的。 SP 中没有动态 SQL。

那么 - 这里有什么故事???

这是SP代码:

CREATE PROCEDURE [dbo].[spr_spr]
    @ListOfIDs dbo.tt_IDsList READONLY, -- (one column - ID)
    @ListOfTwoIDs dbo.tt_TwoIDsRelationList READONLY, -- (two columns - FirstID, SecondID)
    @SomeID int = NULL
AS

IF @SomeID IS NULL 
    SELECT  ..... , 
            cast ( (CASE WHEN le.ID IS NOT NULL THEN 1 ELSE 0 END) as bit) as HasLinkedID 
    FROM        @ListOfIDs ids
    JOIN        dbo.tbl1 ra             ON  ids.ID = ra.RR_RowID                                         
    JOIN        dbo.tbl2 rr             ON  ra.RR_RowID = rr.RowID
    JOIN        dbo.tbl3 res            ON  res.tbl3ID = ra.tbl3ID
    JOIN        dbo.tbl4 cal            ON  cal.ObjectID = rr.ObjectID 
    JOIN        @ListOfTwoIDs IdsRel    ON  cal.FirstID = IdsRel.FirstID
                                        AND res.SecondID = IdsRel.SecondID
    LEFT JOIN   dbo.tbl5 p              ON  ra.tbl5ID = p.tbl5ID 
    LEFT JOIN   dbo.tbl6 le             ON  le.tbl6ID = ra.tbl6ID

ELSE
    .... -- same query with one change

【问题讨论】:

能看到SP代码吗? 同意@jyparask,最好提供您的代码供我们考虑=) 您提供的第一个链接中接受的答案应该可以解决问题。只需将输入参数复制到局部变量中,然后使用它们即可。 “将查询作为查询执行”是什么意思?你能展示一下运行速度快的代码吗? 上次重新编译 SP 是什么时候?如果它是旧的,它可能没有使用最新的索引。 【参考方案1】:

这是解决方案:

CREATE TABLE #ListOfIDs (ID int)
insert into #ListOfIDs (ID) select ID from @ListOfIDs 

CREATE TABLE #ListOfTwoIDs (FirstID int, SecondID int)
insert into #ListOfTwoIDs (FirstID, SecondID) select FirstID, SecondID from @ListOfTwoIDs

我猜问题出在表类型参数上,但我仍然不明白为什么以及是什么...

【讨论】:

以上是关于像存储过程一样慢,像查询一样快 - 不是参数嗅探的主要内容,如果未能解决你的问题,请参考以下文章

Shadow DOM 是不是像 React.js 中的 Virtual DOM 一样快?

调用过程时显示存储过程查询

开始一个过程,而不是像孩子一样

Presto SQL 是不是像 SQL Server 一样支持使用 CTE 进行递归查询?例如员工等级

Snowflake 中的存储过程能否提供一个表值输出,就像我们在 SQL Server 中得到的一样

如果我不能像以前一样选择相同或相似的密码,它是不是以明文形式存储在某处?