【问题标题】:Get an actual plan for a stored function获取存储函数的实际计划
【发布时间】:2015-06-10 17:22:30
【问题描述】:

我想为我的标量函数制定一个执行计划,因为它与我只运行一个函数体时的执行计划不同。前段时间我也遇到过同样的情况,我通过对索引进行碎片整理来解决它(由于高碎片,函数没有使用碎片索引,但纯查询使用了)。但现在我的碎片

我可以得到正确的估计执行计划,但是当我想得到一个实际的计划时, 我几乎一无所获。

所以在这里我只得到了无用的外部查询计划,但看不到函数中发生了什么。

可以修复吗?


预计执行计划:

<ParameterList>
  <ColumnReference Column="@DateTo" ParameterCompiledValue="NULL" />
  <ColumnReference Column="@DateFrom" ParameterCompiledValue="NULL" />
  <ColumnReference Column="@ServerID" ParameterCompiledValue="NULL" />
  <ColumnReference Column="@ResourceTypeID" ParameterCompiledValue="NULL" />
</ParameterList>

我找到了函数的实际执行计划(感谢 Sql Server Profiler)

纯查询的实际计划(快速): 功能(慢):

这个函数只是从表中取出一些 XML 字段并将它们连接到一个大的 XML 文件中:

ALTER FUNCTION [dbo].[fn_GetErrorXML]
(   
    @DateFrom datetime,     
    @DateTo datetime,       
    @ResourceTypeID bigint,  
    @ServerID int           
)
RETURNS NVARCHAR(MAX) 
AS
BEGIN 

    DECLARE @ErrorDescription VARCHAR(MAX)
    SET @ErrorDescription = '<root>';
    WITH CTE AS
    (   

        SELECT 
            d.GeneratedOnUtc,
            ErrorDescription = cast(d.Data as nvarchar(max))
        FROM dbo.AgentData d
          INNER JOIN dbo.Agent a ON a.CheckID = d.CheckID
          INNER JOIN dbo.Server s ON a.ServerID = s.ID
        WHERE d.EventType = 'Result' AND
              a.ResourceTypeID & @ResourceTypeID > 0 AND
              s.ID = @ServerID AND
              d.GeneratedOnUtc between @DateFrom AND @DateTo AND
              d.Result = 0                            
    )
    SELECT @ErrorDescription = @ErrorDescription + cte.ErrorDescription
    FROM CTE    
    ORDER BY cte.GeneratedOnUtc ASC

    RETURN(@ErrorDescription + '</root>')
END

【问题讨论】:

  • 可能是参数嗅探。您可能会从缓存中提取计划并查看它使用哪些参数进行编译,然后通过将逻辑放入存储过程并首先使用这些参数值执行它,然后再使用问题中显示的参数值来重现问题。
  • 您还可以使用分析器或扩展事件检索实际计划。这里讨论了这种行为的原因dba.stackexchange.com/a/29749/3690
  • @MartinSmith,你能详细解释一下吗?
  • 在估计的计划中你能不能把它看成XML,看到ParameterCompiledValues?
  • 这绝对是内联表值函数的完美候选者。

标签: sql sql-server sql-server-2008-r2 sql-execution-plan


【解决方案1】:

好吧,回答我最初的问题:您可以使用 SQL Server Profiler 并分析您的数据库并获取所有执行查询的计划,只需在 new trace 设置中切换一个复选框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-24
    • 2019-11-30
    • 1970-01-01
    • 2017-01-01
    相关资源
    最近更新 更多