Rad*_*hiu 8 sql-server execution-plan azure-sql-database recompile query-performance
我有一个 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 RECOMPILE 的计划中,我的计划中有一部分时间花在移动无用数据上,这些数据稍后由 FILTER 运算符过滤(您可以看到 0B 从 FILTER 中出来)。
unique_valueFILTER 运算符具有过程 (和)附带的所有过滤参数some_value以及在嵌套级别中确定的一些其他过滤参数。嵌套级别本身包含其他 TVF,其参数由 OUTER APPLY'ed 查询确定。
在 OPTION RECOMPILE 版本中,当从磁盘读取数据时,这些参数被下推到执行计划(我猜这称为谓词下推)并直接在第一步中进行过滤。
根据我的观察,这是我对为什么会发生这种情况以及为什么 OPTION RECOMPILE 计划更有效的结论。您可以在下面看到同一个表的相同数据访问以及更高效的 OPTION RECOMPILE 计划的一部分。
现在,我的问题是为什么 OPTION RECOMPILE 计划的行为与仅为新查询生成新计划(传递给它的参数/值相同)时的行为不同。选项重新编译有什么作用?
我尝试在线搜索,看看它是否确实“强制”谓词下推,但我找不到任何具体的信息。
您可以在此处找到执行缓慢的匿名计划。此外,OPTION RECOMPILE 执行的匿名计划位于此处。
我尝试使用 OPTION (RECOMPILE) 运行一次查询,然后删除提示并立即再次运行查询(两次参数相同)。第一次跑得快,第二次跑得慢。
我确实考虑过生成“快速”计划,希望将其存储在缓存中,并在不再指定 OPTION RECOMPILE 时重用。但是,我相信查询计划哈希有所不同,并且缓存的计划不会被重用,因为存在的更改不仅仅是传递到过滤子句的值。
Pau*_*ite 20
现在,我的问题是为什么 OPTION RECOMPILE 计划的行为与仅为新查询生成新计划(传递给它的参数/值相同)时的行为不同。选项重新编译有什么作用?
主要的事情OPTION (RECOMPILE)是为任何参数的当前值编译一个计划,而不是重用任何缓存的计划。新生成的计划不会被缓存以供重用。
它启用的第二件事是参数嵌入优化。SQL Server 在优化之前将任何参数替换为其文字值。
这听起来可能微不足道,但可以实现重要的简化。例如,可以尽早评估该值所属的任何类型转换或复杂表达式(常量折叠)。请注意屏幕截图中的 ,将提供的varcharCONVERT_IMPLICIT值转换为nvarchar。我注意到您的数据库已启用强制参数化。
您的计划很大并且是匿名的,但我建议参数嵌入及其带来的重大简化是性能显着提高的原因。
当您运行相同的查询时,如果没有OPTION (RECOMPILE)相同的简化是不可能的,因为 SQL Server 无法安全地嵌入参数值,因为计划可能会重复用于不同的值。
更多信息和背景请参阅我的文章(上面链接)参数嗅探、嵌入和重新编译选项。它包含一个工作示例,逐步展示参数嵌入和常量折叠如何改进执行计划。
| 归档时间: |
|
| 查看次数: |
1456 次 |
| 最近记录: |