pet*_*ter 11 sql-server execution-plan functions merge-replication
我在 SQL 服务器上有这个查询,一个合并复制查询:
SELECT DISTINCT
b.tablenick,
b.rowguid,
c.generation,
sys.fn_MSgeneration_downloadonly
(
c.generation,
c.tablenick
)
FROM #belong b
LEFT OUTER JOIN dbo.MSmerge_contents c ON
c.tablenick = b.tablenick
AND c.rowguid = b.rowguid;
Run Code Online (Sandbox Code Playgroud)
估计的查询计划包括 3 个查询的信息:
实际的查询计划仅包括以下信息:
没有关于功能。为什么实际方案中缺少功能信息?
我尝试了这些选项:
SET STATISTICS PROFILE ON
SET STATISTICS XML ON
Run Code Online (Sandbox Code Playgroud)
它创建了一个实际计划,但它缺少第 2 部分和第 3 部分,这与我在 Management Studio 中使用实际查询计划选项时相同。
例如,如果我要使用 Profiler 来捕获有关函数调用的信息,我会选择哪些事件?
没有找到与查询计划特别相关的答案,但我分析了 SP:StmtStarting 和 SP:StmtCompleted 并显示了函数调用。
Pau*_*ite 17
和功能无关。为什么实际方案中缺少功能信息?
这是设计使然,出于性能原因。
定义中包含BEGIN
和 的函数END
为每个输入行创建一个新的 T-SQL 堆栈框架。换句话说,函数体是为每个输入行单独执行的。这个单一的事实解释了与 T-SQL 标量和多语句函数相关的大多数性能问题(注意内联表值函数不使用BEGIN...END
语法)。
在您的问题的上下文中,这将导致SHOWPLAN
每一行的完整输出。XML 计划输出非常冗长且生成成本很高,因此一般而言,为每一行生成完整的输出将是一个坏主意。
考虑下面在AdventureWorks示例数据库中创建的 T-SQL 标量函数,它返回给定 ID 的产品名称:
CREATE FUNCTION dbo.DumbNameLookup
(
@ProductID integer
)
RETURNS dbo.Name
AS
BEGIN
RETURN
(
SELECT
p.Name
FROM Production.Product AS p
WHERE
p.ProductID = @ProductID
);
END;
Run Code Online (Sandbox Code Playgroud)
执行前计划(SSMS 中的估计计划)显示父语句和嵌套函数调用的计划信息:
-- Pre-execution plan shows main query and nested function call
SET SHOWPLAN_XML ON;
GO
SELECT dbo.DumbNameLookup(1);
GO
SET SHOWPLAN_XML OFF;
Run Code Online (Sandbox Code Playgroud)
SSMS 输出:
在SQL Sentry Plan Explorer中查看的相同 XML更清楚地显示了调用的嵌套性质:
当请求执行后计划输出时,SSMS 仅显示主查询的详细信息:
-- Post-execution plan shows main query only
SET STATISTICS XML ON;
SELECT dbo.DumbNameLookup(1);
SET STATISTICS XML OFF;
Run Code Online (Sandbox Code Playgroud)
可以使用SQL Server Profiler 中的Showplan XML Statistics Profile Event Class,使用多次调用该函数的查询(每个输入行一次)来显示其他方式的性能影响:
SELECT TOP (5)
p.ProductID,
dbo.DumbNameLookup(p.ProductID)
FROM Production.Product AS p;
Run Code Online (Sandbox Code Playgroud)
探查器输出:
函数执行有五个单独的执行后计划,父查询有一个。五个函数计划在分析器下部窗格中如下所示:
父查询计划是:
执行不带TOP (5)
子句的查询会为 Product 表中的 504 行中的每一行生成完整的执行计划。您可能会看到这将如何在更大的表中迅速失控。
触发器的情况正好相反。这些不显示任何执行前计划信息,但包括执行后计划。这反映了触发器的基于集合的性质;每个都为所有受影响的行触发一次,而不是每行触发一次。
归档时间: |
|
查看次数: |
2172 次 |
最近记录: |