AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 120316
Accepted
James Anderson
James Anderson
Asked: 2015-11-07 06:24:06 +0800 CST2015-11-07 06:24:06 +0800 CST 2015-11-07 06:24:06 +0800 CST

使用 fn_validate_plan_guide 的计划指南验证给出误报

  • 772

在为引用名为“#test”的临时表的存储过程中的一段 SQL 验证计划指南时,函数 fn_validate_plan_guide 返回错误:对象名称“#test”无效。

但是计划指南仍然将查询提示推送到 SQL 中,并实现了所需的执行。

这是否突出了 fn_validate_plan_guide 函数的问题?

下面的脚本重现了这个问题。

--Enable the actual execution plan before running the query so the plans can be compared

USE [msdb]
GO

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[test]
AS
BEGIN
    CREATE TABLE #test 
    (
        ID INT
    )

    INSERT INTO #test
    SELECT ROW_NUMBER() OVER(ORDER BY job_id) 
    FROM dbo.sysjobs

    SELECT * 
    FROM #test t
    JOIN #test t2 ON t.ID = t2.ID

    DROP TABLE #Test 
END
GO

--Execution before the plan guide is created will have a hash join in the second batch
EXEC msdb.dbo.test
GO

--Create the plan guide
EXEC sp_create_plan_guide 'test',
'   SELECT * 
    FROM #test t
    JOIN #test t2 ON t.ID = t2.ID', 
'OBJECT', 'dbo.test', NULL, 'OPTION (MERGE JOIN)'
GO

--Validate the plan guide. This returns the error "Invalid object name '#test'."
SELECT 
    plan_guide_id, msgnum, severity, state, message, 
    name, create_date, is_disabled, query_text, scope_type_desc, scope_batch, parameters, hints
FROM sys.plan_guides
CROSS APPLY fn_validate_plan_guide(plan_guide_id);
GO

--Execution after the plan guide is created will have a merge join in the second batch
EXEC msdb.dbo.test
GO

EXEC sp_control_plan_guide 'DISABLE', 'test'
GO

--Execution after the plan guide is disabled will go back to having a hash join in the second batch
EXEC msdb.dbo.test
GO

EXEC sp_control_plan_guide 'ENABLE', 'test'
GO

--Execution after the plan guide is re-enabled will go back to having a merge join in the second batch
EXEC msdb.dbo.test
GO

--Clean up
EXEC sp_control_plan_guide 'DROP', 'test'
GO

DROP PROCEDURE test
GO

这个函数给出的错误是误报,还是这些只是计划指南可能失败的警告,还是我没有想到的其他事情?

我在这里用上面的文字创建了一个连接项目,但我还没有收到回复。

sql-server sql-server-2012
  • 1 1 个回答
  • 296 Views

1 个回答

  • Voted
  1. Best Answer
    Paul White
    2016-04-07T03:32:58+08:002016-04-07T03:32:58+08:00

    是的,这是sys.fn_validate_plan_guide的限制,可能会导致误报(不是误报)。

    服务器尝试只编译计划指南中的语句,而不是整个批处理(在本例中为存储过程)。请求失败,因为临时表定义不是编译的一部分。

    我无法用表变量重现相同的问题:

    Microsoft SQL Server 2012 (SP3-CU2) (KB3137746) - 11.0.6523.0 (X64)
        2016 年 3 月 2 日 21:29:16
        版权所有 (c) 微软公司
        Windows NT 6.3(内部版本 10586:)上的开发人员版(64 位)

    计划验证和指南应用程序工作正常。

    解决方法

    请求调用过程的估计计划成功,生成的批处理计划显示指导计划,语句根节点的属性在 SSMS 中显示正确的PlanGuideDB和PlanGuideName属性:

    预计计划

    另一种方法是在调用sys.fn_validate_plan_guide的会话上创建临时表(从过程定义中复制) 。

    CREATE TABLE #test 
    (
        ID INT
    );
    
    -- Succeeds
    SELECT 
        PG.plan_guide_id,
        PG.name,
        PG.scope_type_desc,
        PG.hints,
        FVPG.msgnum,
        FVPG.severity,
        FVPG.[state],
        FVPG.[message]
    FROM sys.plan_guides AS PG
    CROSS APPLY sys.fn_validate_plan_guide(PG.plan_guide_id) AS FVPG;
    
    DROP TABLE #test;
    

    当错误指的是缺少#object 时,其中任何一个都可用于验证 sys.fn_validate_plan_guide 的否定结果。

    • 2

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve