如何在 SSMS 中批量显示单个查询的实际查询计划?
How do you show the actual query plan for a single query in a batch in SSMS?
我有一个正在尝试优化的存储过程,它接受一个 table 变量作为参数。 table 变量只有一列,用于传入主键列表。测试时,我创建了一个虚拟 table 变量,运行 一堆 INSERT 语句向其添加虚拟值,并将其传递到存储过程中。这工作正常,但是当我想查看实际的查询执行计划时,SSMS 会为所有 INSERT 语句和存储过程编译一个查询计划。所以,如果我有 1000 个虚拟 INSERT 语句,SSMS 就会崩溃。不幸的是,table 变量必须与存储过程在同一批中执行,所以我不能 enable/disable 批量查询计划。
有没有办法只为存储过程编译实际的查询计划,忽略批处理中的所有 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 服务器实例是 运行ning SQL SERVER 2014。
使用递归 cte 之类的东西生成您的 val,然后插入 table。这将导致生成值的计划,然后是插入 table 的计划。不要单独插入。您也可以将所有这些值放入一个插入件中。
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 @
如果你想完全删除插入计划,你需要先插入到持久性 table,比如用户 table 或临时 table,然后 运行 非插入 TSQL 本身。
实现此目的的一种方法是不依赖 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
这样服务器将 return 仅针对中间代码查询计划。在内部,SSMS 会为整个批次执行此操作。请注意,通过此更改,SSMS 将不会在结果面板中显示 "execution plan" 选项卡,而是会 returned(或更准确地说,每个计划一个)。您必须手动单击它们,然后 SSMS 将显示它的图形计划。
我有一个正在尝试优化的存储过程,它接受一个 table 变量作为参数。 table 变量只有一列,用于传入主键列表。测试时,我创建了一个虚拟 table 变量,运行 一堆 INSERT 语句向其添加虚拟值,并将其传递到存储过程中。这工作正常,但是当我想查看实际的查询执行计划时,SSMS 会为所有 INSERT 语句和存储过程编译一个查询计划。所以,如果我有 1000 个虚拟 INSERT 语句,SSMS 就会崩溃。不幸的是,table 变量必须与存储过程在同一批中执行,所以我不能 enable/disable 批量查询计划。
有没有办法只为存储过程编译实际的查询计划,忽略批处理中的所有 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 服务器实例是 运行ning SQL SERVER 2014。
使用递归 cte 之类的东西生成您的 val,然后插入 table。这将导致生成值的计划,然后是插入 table 的计划。不要单独插入。您也可以将所有这些值放入一个插入件中。
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 @
如果你想完全删除插入计划,你需要先插入到持久性 table,比如用户 table 或临时 table,然后 运行 非插入 TSQL 本身。
实现此目的的一种方法是不依赖 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
这样服务器将 return 仅针对中间代码查询计划。在内部,SSMS 会为整个批次执行此操作。请注意,通过此更改,SSMS 将不会在结果面板中显示 "execution plan" 选项卡,而是会 returned(或更准确地说,每个计划一个)。您必须手动单击它们,然后 SSMS 将显示它的图形计划。