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 / 问题 / 135063
Accepted
Henrik Staun Poulsen
Henrik Staun Poulsen
Asked: 2016-04-13 05:12:34 +0800 CST2016-04-13 05:12:34 +0800 CST 2016-04-13 05:12:34 +0800 CST

如何获得估计的子树成本?

  • 772

如果我有一个返回 query_plan 的查询,例如这样:

    SELECT TOP 1000 st.TEXT
    ,cp.size_in_bytes
    ,cp.plan_handle
    ,QP.query_plan
FROM sys.dm_exec_cached_plans AS cp
CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS QP
WHERE cp.objtype = N'Adhoc'
    AND cp.usecounts = 1

然后我可以单击 query_plan 并将鼠标悬停在最左侧的图标上,其中提示文本将列出估计的子树成本。

有没有办法将它Estimated Subtree Cost作为我的查询的单独列?

我知道这个数字是无单位的,并且是指大约 20 年前的特定开发人员 PC。即便如此,我认为如果统计数据不是太远,它可能会告诉我查询需要多长时间。

我已经非常努力地向 Google 搜索此信息,但即使 dba.stackexchange.com 也是空的。

sql-server sql-server-2014
  • 2 2 个回答
  • 1586 Views

2 个回答

  • Voted
  1. Best Answer
    GoodwinSQL
    2016-04-13T05:27:01+08:002016-04-13T05:27:01+08:00

    我相信您必须做一些 XML 查询工作才能获得估计的成本。

    看看这是不是你要找的:

       ;WITH XMLNAMESPACES  
        (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') 
        SELECT TOP 1000 st.text
            ,cp.size_in_bytes
            ,cp.plan_handle
            ,QP.query_plan
            ,n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS StatementSubTreeCost
        FROM sys.dm_exec_cached_plans AS cp
        CROSS APPLY sys.dm_exec_sql_text(cp.plan_handle) AS st
        CROSS APPLY sys.dm_exec_query_plan(cp.plan_handle) AS QP
        CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn(n)
        WHERE cp.objtype = N'Adhoc'
            AND cp.usecounts = 1
        OPTION(RECOMPILE);
    

    这将返回批处理中单个语句的成本。如果您需要整个批次的估计子树总成本,您可能需要在某些分组中工作。

    • 8
  2. Henrik Staun Poulsen
    2016-04-16T00:06:40+08:002016-04-16T00:06:40+08:00

    这是我如何使用我的问题的答案。

    我是 sp_whoisactive 的忠实粉丝。如果没有,请停止阅读;在这里下载。

    因此,我将其设置为每 10 分钟收集一次快照,如下所示:

    DROP TABLE dbo.HESPOmonitoring_output
    DECLARE @s VARCHAR(MAX)
    EXEC sp_WhoIsActive 
        @output_column_list = '[login_name][dd%][session_id][program%][sql_com%][sql_text][block%][reads][writes][physical_reads][query_plan][used_memory][tempdb%][wait%][start_time][collection_time][host%][additional%]', @get_outer_command=1, @get_additional_info=1,
        @return_schema = 1, @get_plans=1, 
        @schema = @s OUTPUT
    SET @s = REPLACE(@s, '<table_name>', 'dbo.HESPOmonitoring_output')
    EXEC(@s)
    ALTER TABLE dbo.HESPOmonitoring_output ADD HESPOmonitoring_outputID BIGINT IDENTITY(1,1) NOT NULL
    go
    SET NOCOUNT ON 
    DECLARE @Started DATETIME=DATEADD(DAY, 3, GETDATE())
    WHILE 1 > 0 BEGIN 
        EXEC sp_WhoIsActive 
            @output_column_list = '[login_name][dd%][session_id][program%][sql_com%][sql_text][block%][reads][writes][physical_reads][query_plan][used_memory][tempdb%][wait%][start_time][collection_time][host%][additional%]', @get_outer_command=1, @get_additional_info=1,
             @get_plans=1, 
            @destination_table = 'dbo.HESPOmonitoring_output'
        WAITFOR DELAY '00:10:00'
        IF GETDATE() > @Started BREAK  
    END 
    

    我已经让它运行了一段时间(最多 3 天)。然后我像这样转换收集到的数据:

    /* this query turns HESPOmonitoring_output in a table with one row per SQL statement */
    Begin TRY
        DROP TABLE #hespo
    END TRY
    BEGIN CATCH
    END CATCH
    ;WITH XMLNAMESPACES  
        (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan') 
         SELECT top 10000 H.Start_Time, H.session_id, MAX(H.program_name) AS program_name, MAX(CAST(H.sql_command AS VARCHAR(max))) AS sql_command
        , MAX(CAST(H.sql_text AS VARCHAR(max))) AS sql_text
        , MAX(H.reads) AS reads
        , MAX(H.physical_reads) AS physical_reads
        , MAX(H.writes) AS writes
        , MAX(H.collection_time) AS collection_time
        , MAX(DATEDIFF(second, start_time, collection_time)) AS RunTime
        , MAX(HESPOmonitoring_outputID) AS MaxHESPOmonitoring_outputID
        , MAX(H.blocking_session_id) AS MaxBlocking_session_id
        , Min(H.blocking_session_id) AS MinBlocking_session_id
        , count_big(*) as RowCnt 
        , MAX(TRY_CAST(n.value('(@StatementSubTreeCost)[1]', 'VARCHAR(128)') AS DECIMAL(18,3))) AS StatementSubTreeCost
        INTO #hespo
        FROM dbo.HESPOmonitoring_output H
        CROSS APPLY query_plan.nodes('/ShowPlanXML/BatchSequence/Batch/Statements/StmtSimple') AS qn(n)
        GROUP BY H.Start_Time, H.session_id
    

    最后我得到一个列表,显示与运行时相比,估计成本在哪里小,而工作根本没有被阻止

    SELECT top 10000 
    H.StatementSubTreeCost/NULLIF(H.RunTime, 0) AS Ratio, H.StatementSubTreeCost, H.RunTime, *
    FROM #hespo H
    WHERE H.MinBlocking_session_id IS NULL
    AND H.RunTime>0
    AND H.StatementSubTreeCost IS NOT NULL
    ORDER BY 1 
    

    这是一个非常有趣的列表,但它带有一点噪音。首先,我选择忽略运行时间少于 10 分钟的快速小型作业,但该限制取决于您的情况。

    现在,找到计划不佳的工作要容易得多。
    非常感谢您的帮助。

    • 1

相关问题

  • 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