【问题标题】:How do you show the actual query plan for a single query in a batch in SSMS?如何在 SSMS 中批量显示单个查询的实际查询计划?
【发布时间】:2018-07-26 17:19:05
【问题描述】:

我有一个正在尝试优化的存储过程,它接受一个表变量作为参数。表变量只有一列,用于传入主键列表。测试时,我创建了一个虚拟表变量,运行一堆 INSERT 语句为其添加虚拟值,并将其传递给存储过程。这很好用,但是当我想查看实际的查询执行计划时,SSMS 会为所有 INSERT 语句和存储过程编译一个查询计划。所以,如果我有 1000 个虚拟 INSERT 语句,SSMS 就会崩溃。不幸的是,表变量必须与存储过程在同一批次中执行,因此我无法按批次启用/禁用查询计划。

有没有办法只编译存储过程的实际查询计划,而忽略批处理中的所有 INSERT 语句?

它是这样的:

DECLARE @dummyIds AS PrimaryKeyTable
INSERT INTO @dummyIds VALUES(1)
INSERT INTO @dummyIds  VALUES(2)
...
INSERT INTO @dummyIds VALUES(1000)

EXEC MyStoredProc @dummyIds

如果我执行包含实际查询计划的批处理,它将生成 1001 个查询计划,而我真的只想要 1 个。

SQL Server 实例正在运行 SQL SERVER 2014。

【问题讨论】:

  • 将所有值放入一个插入中。

标签: sql sql-server database ssms sql-optimization


【解决方案1】:

实现此目的的一种方法是不依赖 SSMS 生成请求查询计划,而是仅在您的测试批次中的所需点执行。为此,只需在待分析查询前手动插入SET STATISTICS XML指令,然后将其禁用,并保持SSMS中的选项禁用。

类似的事情会做:

DECLARE @dummyIds AS PrimaryKeyTable
INSERT INTO @dummyIds VALUES(1)
INSERT INTO @dummyIds  VALUES(2)
...
INSERT INTO @dummyIds VALUES(1000)

SET STATISTICS XML ON          --Enable plan generation
EXEC MyStoredProc @dummyIds
SET STATISTICS XML OFF         --Disable plan generation

这样服务器将只返回中间代码的查询计划。在内部,SSMS 对整个批次都执行此操作。请注意,通过此更改,SSMS 将不会在结果面板中显示“执行计划”选项卡,而是会返回一个带有单独 XML 文档的额外结果集(或更准确地说,每个计划一个)。您必须手动单击它们,然后 SSMS 将显示它的图形计划。

【讨论】:

  • 谢谢!这完美地工作。我尝试以与您在此处使用 STATISTICS XML 相同的方式使用 SHOWPLAN_ALL,但它出错了,因为它仅适用于批处理级别。所以,我假设类似的方法都是批次级别的,但显然我错了。
【解决方案2】:

使用递归 cte 之类的东西来生成您的 val,然后插入到表中。这将导致计划生成值,然后计划插入到表中。不要做单独的插入。您也可以将所有这些值放入一个插入中。

DECLARE @ TABLE (val INT) 

;with cte AS (
SELECT 1 AS col_

UNION ALL 

SELECT col_ + 1
FROM cte
WHERE col_ < 1000
)

INSERT INTO @
SELECT * 
FROM cte 
OPTION (MAXRECURSION 0)


SELECT * 
FROM @

如果要完全删除插入计划,则需要先插入持久表,如用户表或临时表,然后自行运行非插入 TSQL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-18
    • 2014-11-11
    • 1970-01-01
    • 2022-06-29
    • 1970-01-01
    • 2012-11-22
    • 1970-01-01
    • 2013-04-20
    相关资源
    最近更新 更多