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 / 问题 / 54782
Accepted
db2
db2
Asked: 2013-12-11 06:58:37 +0800 CST2013-12-11 06:58:37 +0800 CST 2013-12-11 06:58:37 +0800 CST

为通过 sp_executesql 调用的查询创建计划指南

  • 772

长话短说,我有一个名为 vwRelatives 的视图,它使用 CTE 递归来构建家谱。它意味着一次查询一个人。

这大约在四分之一秒内运行:

SELECT * FROM vwRelatives WHERE person_id = 5

这(从应用程序执行查询的方式)大约需要 4.5 秒:

exec sp_executesql N'SELECT * FROM vwRelatives WHERE person_id = @P1',N'@P1 int',5

(请注意,我已经稍微简化了查询。真实的东西有一个明确的列列表和一个ORDER BY,但WHERE语义是相同的。我在任何一个版本中都得到相同的症状。)

person_id = 5最有可能的是,SQL Server在为第一个查询创建执行计划时能够考虑到,但是参数化它会导致整个视图运行,然后按 person_id 过滤。

所以我想我会创建一个计划指南。现在我有两个问题。

这些是我正在采取的步骤,似乎没有效果。

首先,运行“好”查询以将其放入计划缓存中...

SELECT * FROM vwRelatives WHERE person_id = 5

...然后执行标准步骤将其变成计划指南...

--Get the 'good' plan
SET @xml_showplan = (
    SELECT query_plan
    FROM sys.dm_exec_query_stats AS qs 
        CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
        CROSS APPLY sys.dm_exec_text_query_plan(qs.plan_handle, DEFAULT, DEFAULT) AS qp
        WHERE st.text LIKE N'SELECT * FROM vwRelatives WHERE person_id = 5'
)

--Apply a plan guide to the meat of the sp_executesql query
EXEC sp_create_plan_guide 
    @name = N'vwRelatives_Test_Plan_Guide', 
    @stmt = N'SELECT * FROM vwRelatives WHERE person_id = @P1', 
    @type = N'SQL',
    @module_or_batch = NULL, 
    @params = N'@P1 int', 
    @hints = @xml_showplan;

这成功完成,但是当我再次运行原来的 sp_executesql 语句时,仍然需要 4.5 秒。我正在运行 Profiler,并且选择了“计划指南成功”和“计划指南不成功”事件。这些事件都没有出现在跟踪中。

我做错了什么导致 SQL Server 无法将此计划指南视为 sp_executesql 查询的匹配项?

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

1 个回答

  • Voted
  1. Best Answer
    db2
    2013-12-11T07:59:39+08:002013-12-11T07:59:39+08:00

    对于那些在尝试创建计划指南时遇到这个问题的人来说,我最初的语法是正确的。它不起作用的原因(我怀疑 - 我在文档中找不到任何确认)是视图使用 CTE 进行递归。显然,这使其无法使用计划指南。

    我最初的问题是,当SELECT通过带有参数的 sp_executesql 发出语句(客户端是 Access 数据库)时,递归视图的性能很差。

    我终于在 Stack Overflow 上遇到了这个老问题,有人遇到了基本相同的问题:

    https://stackoverflow.com/questions/4226035/why-does-a-query-slow-down-drastical-if-in-the-where-clause-a-constant-is-repl

    我开始怀疑是否需要通过将递归推送到用户定义的函数来欺骗/帮助查询优化器,这证实了怀疑。我将视图中的所有 CTE 移动到一个内联 UDF 中,该 UDF@person_id直接在递归的锚点中使用参数,现在即使使用 sp_executesql 也快得令人愉快。

    所以,不是我最初认为我需要的解决方案,但我会接受它。(这种方式也可能更直接。我不必担心将计划指南附加到 Access 可能构建的查询的每个细微变化中。)

    • 5

相关问题

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

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

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

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

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

Sidebar

Stats

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

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

    • 3 个回答
  • Marko Smith

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

    • 3 个回答
  • Marko Smith

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

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • 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
    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
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +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