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 / 问题 / 54845
Accepted
Gabe
Gabe
Asked: 2013-12-12 08:05:00 +0800 CST2013-12-12 08:05:00 +0800 CST 2013-12-12 08:05:00 +0800 CST

SentryOne Plan Explorer 是否计算 UDF 中的读取数?

  • 772

我有这样的查询:

select dbo.fn_complexFunction(t.id)
from mytable t

在SQL Sentry Plan Explorer中,我注意到我必须运行 Get Estimated Plan 以使查询计划包含 UDF。

运行“获取实际计划”时,逻辑读取和其他指标似乎不包括 UDF 中发生的操作。在这种情况下,使用 Profiler 是唯一的解决方法吗?

sql-server sql-server-2008
  • 1 1 个回答
  • 741 Views

1 个回答

  • Voted
  1. Best Answer
    Aaron Bertrand
    2013-12-12T09:26:03+08:002013-12-12T09:26:03+08:00

    我们这里最大的问题是:

    1. 就像@JNK 所说的那样,SQL Server 混淆了 UDF 的使用,并且无论如何都会用它们做一些糟糕的事情(比如总是估计一行)。当您在 SSMS 中生成实际计划时,您也根本看不到它的用途。计划资源管理器受到相同的限制,因为它只能提供有关 SQL Server 提供的计划的信息。
    2. 在生成实际计划时,代码依赖于不同来源的运行时指标。不幸的是,计划 XML 不包括函数调用,并且 SQL Server 不显示函数在使用SET STATISTICS IO ON;任何一个时产生的 I/O(这就是Table I/O选项卡的填充方式)。

    考虑以下针对 AdventureWorks2012 的视图和函数。这只是一个愚蠢的尝试,在给定标题表中的随机行的情况下,从详细信息表中返回随机行 - 主要是为了确保我们每次都生成尽可能多的 I/O。

    CREATE VIEW dbo.myview 
    WITH SCHEMABINDING
    AS
      SELECT TOP (100000) rowguid, SalesOrderID, n = NEWID() 
        FROM Sales.SalesOrderDetail ORDER BY NEWID();
    GO
    
    CREATE FUNCTION dbo.whatever(@SalesOrderID INT)
    RETURNS UNIQUEIDENTIFIER
    WITH SCHEMABINDING
    AS
    BEGIN
      RETURN 
      (
        SELECT TOP (1) rowguid FROM dbo.myview 
         WHERE SalesOrderID = @SalesOrderID ORDER BY n
      );
    END
    GO
    

    Management Studio 会(和不会)告诉您的内容

    在 SSMS 中执行以下查询:

    SET STATISTICS IO ON;
    
      SELECT TOP (5) SalesOrderID, dbo.whatever(SalesOrderID) 
        FROM Sales.SalesOrderHeader ORDER BY NEWID();
    
    SET STATISTICS IO OFF;
    

    当你估计一个计划时,你会得到一个查询计划和一个函数计划(不是你可能希望的 5 个):

    Management Studio 中的预估计划

    显然,您根本得不到任何 I/O 数据,因为实际上并未执行查询。现在,生成一个实际的计划。您在结果网格中获得了预期的 5 行,以下计划(绝对没有明显提及 UDF,除了在 XML 中您可以找到它作为查询文本的一部分和标量运算符的一部分):

    Management Studio 中的实际计划

    以及以下STATISTICS IO输出(完全没有提及Sales.SalesOrderDetail,即使我们知道它必须从该表中读取):

    表 'SalesOrderHeader'。扫描计数 1,逻辑读取 57,物理读取 0,预读读取 0,lob 逻辑读取 0,lob 物理读取 0,lob 预读读取 0。

    Plan Explorer 告诉您什么

    当 PE 为同一查询生成估计计划时,它知道的事情与 SSMS 相同。然而,它确实以一种稍微更直观的方式显示事物。例如,外部查询的估计计划显示了函数的输出如何与查询的输出相结合,并且立即清楚 - 在单个计划图中 - 两个表都有 I/O:

    Plan Explorer 中的预估计划

    它还单独显示了函数的计划,我只是为了完整性才包括在内:

    Plan Explorer 中 UDF 的预估计划

    现在,让我们来看看一个实际的计划,它的用处要大上千倍。这里的缺点是,同样,它只有 SQL Server 决定显示的信息,因此它只能公开 SQL Server 提供的图形计划图。这不是某人决定不向您展示有用的东西的情况;根据提供的计划 XML,它只是一无所知。在这种情况下,就像在 SSMS 中一样,您只能看到外部查询的计划,就好像根本没有调用该函数一样:

    Plan Explorer 中的实际计划

    表 I/O 选项卡也仍然依赖于 的输出STATISTICS IO,它也忽略函数调用中执行的任何活动:

    Plan Explorer 中实际计划的表 I/O

    但是,PE 会为您获取整个调用堆栈。我偶尔会听到有人问,“Pffft,我什么时候需要调用堆栈?” 好吧,您实际上可以分解每个函数调用所花费的时间、使用的 CPU 和读取次数(对于 TVF,还包括生成的行数) :

    Plan Explorer 中的调用堆栈,显示 UDF 调用

    不幸的是,您无法将它关联回 I/O 来自哪个表(同样,因为 SQL Server 不提供该信息),并且它没有标有 UDF 名称(因为它被捕获为临时语句,而不是函数调用本身)。但是它让您看到的是您的 UDF 是什么狗,而 Management Studio 没有。您仍然需要加入一些点,但点数较少,而且它们靠得更近。

    关于探查器

    最后,我强烈建议远离 Profiler,除非它是为了设置您要编写脚本的服务器端跟踪,然后在任何 UI 工具的范围之外运行。对生产系统使用 Profiler 几乎肯定会导致比它解决的问题更多的问题。如果您想获取此信息,请使用服务器端跟踪或扩展事件,并确保非常明智地进行过滤。即使没有分析器,跟踪也会影响您的服务器,并且通过扩展事件检索显示计划也不是世界上最有效的事情。

    • 11

相关问题

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

  • 我在索引上放了多少“填充”?

  • 是否有开发人员遵循数据库更改的“最佳实践”类型流程?

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

  • 从 SQL Server 2008 降级到 2005

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