标签: recompile

为什么 OPTION RECOMPILE 会导致谓词下推?

我有一个 SQL 查询,它是由一堆嵌套的视图和表值函数组成的,深度至少为 4 层(我没有时间或耐心去完成这一切,它有数百行代码在每个级别)。

我一直试图理解为什么当我使用选项(重新编译)运行基本查询时它运行得非常快,但是当我在没有这个选项的情况下运行它时,它运行得非常慢。

我已确保在发生这种情况之前清除计划缓存,即使在生成新计划时,它也不是最佳的,但是,选项(重新编译)速度很快。

我检查了这两个计划,并注意到对于带有选项(重新编译)的计划,传递的参数。

SELECT [p].[Activity]
    ,[p].[ActivityType]
    ,[p].[Company]
    ,[p].[Flags]
    ,[p].[Id]
    ,[p].[Name]
    ,[p].[Priority]
    ,[p].[Filters]
    ,[p].[Priority]
    ,[p].[Classification]
    ,[p].[Number]
    ,[p].[TaskFilter]
    ,[p].[TaskType]
    ,[p].[User]
FROM (
    SELECT *
    FROM [ActivProdStatuses]('ProdJobTask', 0)
    ) AS [p]
WHERE (
        (   ([p].[User] = 'some_value') AND (([p].[Flags] & 8) = 0) ) 
           AND ([p].[Activity] = 'unique_value') 
        )
    AND  
      (CASE 
        WHEN ([p].[Flags] & 4) <> 0
         THEN CAST(1 AS BIT)
         ELSE CAST(0 AS BIT)
       END = 1 )
ORDER BY [p].[Priority]
OPTION (RECOMPILE)
Run Code Online (Sandbox Code Playgroud)

在没有 OPTION …

sql-server execution-plan azure-sql-database recompile query-performance

8
推荐指数
1
解决办法
1456
查看次数

为什么在将结果选择到标量变量中时,SQL Server 不使用 OPTION(RECOMPILE) 执行常量 (UNION ALL) 分支消除?

我们使用一些“聚合”视图使用鉴别器从多个表中进行选择(注意:这些视图不是分区视图,因为鉴别器不在基表中)。这在使用 时通常效果很好option(recompile),因为查询计划器将在选择查询计划之前消除不可到达的union all路径。

然而,当将结果选择为标量变量时,这种常量折叠优化似乎失败了。将结果选择到临时表变量中不会对重新编译进行去优化。

下面是SQL Server 2017中的一个复现案例:

-- A table, don't need any data.
create table [test].test_table (col1 int, primary key (col1));

-- A simple 'aggregate' view. Using the same table here is irrelevant and,
-- while the view shows the scenario, it might not be required to reproduce the issue.
create view [test].test_view as
select col1, descrim = 1 from [test].test_table
union all
select col1, descrim = 2 from [test].test_table
Run Code Online (Sandbox Code Playgroud)

普通查询,其结果在优化的查询计划感人只有 …

sql-server optimization sql-server-2017 recompile

5
推荐指数
1
解决办法
138
查看次数

包含大量 ComputeScalar 操作的执行计划

我在使用和不使用 OPTION (RECOMPILE) 的情况下执行了相同的查询。当我比较这两个计划时,我看到的一个主要区别是,没有选项重新编译的计划显示了很多 ComputeScalar 运算符,而另一个则没有。

以下是两个计划:

不带选项重新编译:https://www.brentozar.com/pastetheplan/ ?id=S1OcZGi85 带选项重新编译:https://www.brentozar.com/pastetheplan/ ?id=ryJAfMsL5

为什么一个计划使用大量计算标量,而另一个计划则不使用?不带选项重新编译的查询需要近 4 分钟才能执行。计算标量操作是否导致速度缓慢?

sql-server execution-plan recompile query-performance

4
推荐指数
1
解决办法
351
查看次数

with recompile 和 Option(recompile) 之间的区别

我在网上读过,它将with recompile重新编译整个过程,而Option(recompile)只会重新编译它所使用的特定语句。如果重新编译过程中的某个语句,是否会影响过程的其他部分,因为现在优化器具有更好的统计信息,以便稍后做出更好的决策(假设选项(重新编译)产生更好的统计信息),从而导致完全重新编译的程序?到底有何with recompile不同option(recompile)

sql-server optimization recompile

0
推荐指数
1
解决办法
1946
查看次数

除了显式刷新缓存或要求重新编译之外,什么会重新编译 SQL Server 2019 中的完整存储过程?

我最近读完 《SQL Server 2008 中的计划缓存》 ,我感到很困惑。看起来,除了完全刷新计划缓存或明确要求重新编译存储过程之外,从 SQL Server 2008 开始,存储过程的重新编译都是在语句级别而不是存储过程级别完成的。

那么,除了显式刷新缓存或要求重新编译(例如WITH RECOMPILE)之外,什么可以在 SQL Server 2019 中重新编译完整的存储过程,而不仅仅是重新编译单个语句呢?

举一个我感到困惑的例子,请考虑以下过程。

CREATE PROCEDURE FOO AS
BEGIN
   SELECT * INTO #temp1 FROM table1
   INSERT BAR1 SELECT * FROM #temp1
   INSERT BAR2 SELECT * FROM #temp1
END
Run Code Online (Sandbox Code Playgroud)

我可以想到很多可能导致SELECT * INTO #temp1 FROM table1重新编译的事情,但是如果没有下一行也重新编译,那么重新编译会很奇怪。这让我觉得 SQL Server 中一定有一些东西会导致整个存储过程重新编译。

stored-procedures t-sql execution-plan recompile sql-server-2019

0
推荐指数
1
解决办法
182
查看次数