获取 SQL Server 中特定对象的前 5 个高效查询计划

问题描述 投票:0回答:1

我正在尝试分析 SQL Server 中特定对象的不同查询执行计划的性能。我的目标是检索前 5 个最有效的查询计划,以便我可以手动比较它们并选择最好的一个来强制执行。

背景 数据库:SQL Server 对象:[指定存储过程] 当前的方法:我一直在使用查询存储功能,但我不确定如何有效地过滤和排名计划。

我尝试过的: 我尝试使用以下 SQL 查询来检索执行计划,但没有得到所需的结果:

 SELECT OBJECT_NAME(object_id), qp.plan_id, qt.query_sql_text, q.query_id, q.query_text_id,
      qp.query_plan, q.avg_compile_memory_kb / 1024 AS avg_compile_memory_mb, q.last_execution_time
FROM sys.query_store_query_text qt
INNER JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
INNER JOIN sys.query_store_plan qp ON qp.query_id = q.query_id
WHERE ISNULL(OBJECT_NAME(q.object_id), 'N/A') = 'axsp_upd_credit_utilisation2'  -- Filter for specific object
  AND qt.query_sql_text LIKE '%(@includeResidualValue bit%' 
ORDER BY q.last_execution_time DESC;

问题

  1. 我如何修改这个查询以确保我获取最多的 基于多个绩效指标的高效计划?
  2. 是否有我应该考虑添加的特定条件或过滤器 有效缩小结果范围?
  3. 一旦我有了具体的执行计划,最好的方法是什么? 确定了最有效的一个?

附加信息 我正在寻找 SQL Server 中有关执行计划分析的最佳实践。 任何有关为此目的有效使用查询存储的见解将不胜感激。

请查看我根据@Charlieface的建议创建的修改后的SQL。您能否确认它是否正确并达到其目的?

SELECT
    o.name AS ObjectName,
    qp.plan_id,
    qt.query_sql_text,
    q.query_id,
    q.query_text_id,
    qp.query_plan,
    SUM(q.avg_compile_memory_kb) / 1024 AS total_compile_memory_mb,  -- Aggregate memory usage
    MAX(q.last_execution_time) AS last_execution_time,
    qsr.execution_type,
    AVG(qsr.avg_duration) AS avg_duration,
    AVG(qsr.avg_cpu_time) AS avg_cpu_time,
    AVG(qsr.avg_logical_io_reads) AS avg_logical_io_reads,
    AVG(qsr.avg_physical_io_reads) AS avg_physical_io_reads,
    SUM(qsr.count_executions) AS total_executions
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan qp ON qp.query_id = q.query_id
JOIN sys.query_store_runtime_stats qsr ON qsr.plan_id = qp.plan_id
JOIN sys.objects o ON o.object_id = q.object_id
WHERE o.name = 'axsp_upd_credit_utilisation2'  -- Filter for specific object
  AND qt.query_sql_text LIKE '%(@includeResidualValue bit%'  -- Filter for specific SQL text
GROUP BY
    o.name,
    qp.plan_id,
    qt.query_sql_text,
    q.query_id,
    q.query_text_id,
    qp.query_plan,
    qsr.execution_type
ORDER BY
    q.query_id,
    qsr.execution_type,  -- Regular execution first
    avg_duration;  -- Order by average duration
sql-server query-optimization sql-execution-plan sql-query-store
1个回答
1
投票

您可以使用

sys.query_store_runtime_stats
视图 获取每个计划的运行时统计信息。例如,您可以通过
avg_duration
列进行订购。

SELECT
  o.name,
  qp.plan_id,
  qt.query_sql_text,
  q.query_id,
  q.query_text_id,
  qp.query_plan,
  q.avg_compile_memory_kb / 1024 AS avg_compile_memory_mb,
  q.last_execution_time,
  qsr.*
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan qp ON qp.query_id = q.query_id
JOIN sys.query_store_runtime_stats qsr ON qsr.plan_id = qp.plan_id
JOIN sys.objects o ON o.object_id = q.object_id
WHERE o.name = 'axsp_upd_credit_utilisation2'  -- Filter for specific object
  AND qt.query_sql_text LIKE '%(@includeResidualValue bit%' 
ORDER BY
  q.query_id,
  sqr.execution_type,  -- regular exec first
  sqr.avg_duration;

请注意此表:

仅对过去的运行时间统计间隔是唯一的。对于当前活动间隔,可能有多行表示

plan_id
引用的计划的运行时统计信息,执行类型由
execution_type
表示。通常,一行表示刷新到磁盘的运行时统计信息,而其他行表示内存中状态。因此,要获取每个时间间隔的实际状态,您需要聚合指标,按
plan_id
execution_type
runtime_stats_interval_id
进行分组。


关于新修改的查询:与其进行巨大的低效

GROUP BY
,不如将计算放入
APPLY
JOIN
中。

SUM(q.avg_compile_memory_kb) / 1024 AS total_compile_memory_mb
是无意义的,它将总结可能多次代表相同计划的行。您可能想要
AVG

查看未完成运行的平均统计数据可能没有意义,仅查看常规运行。

SELECT
    o.name AS ObjectName,
    qp.plan_id,
    qt.query_sql_text,
    q.query_id,
    q.query_text_id,
    qp.query_plan,
    q.avg_compile_memory_kb / 1024 AS total_compile_memory_mb,  -- Aggregate memory usage
    q.last_execution_time AS last_execution_time,
    qsr.*
FROM sys.query_store_query_text qt
JOIN sys.query_store_query q ON qt.query_text_id = q.query_text_id
JOIN sys.query_store_plan qp ON qp.query_id = q.query_id
JOIN sys.objects o ON o.object_id = q.object_id
CROSS APPLY (
    SELECT
      AVG(qsr.avg_duration) AS avg_duration,
      AVG(qsr.avg_cpu_time) AS avg_cpu_time,
      AVG(qsr.avg_logical_io_reads) AS avg_logical_io_reads,
      AVG(qsr.avg_physical_io_reads) AS avg_physical_io_reads,
      SUM(qsr.count_executions) AS total_executions
    FROM sys.query_store_runtime_stats qsr
    WHERE qsr.plan_id = qp.plan_id
      AND qsr.execution_type = 0  -- Regular execution only
    GROUP BY
      qsr.execution_type
) qsr
WHERE o.name = 'axsp_upd_credit_utilisation2'  -- Filter for specific object
  AND qt.query_sql_text LIKE '%(@includeResidualValue bit%'  -- Filter for specific SQL text
ORDER BY
    q.query_id,
    avg_duration;  -- Order by average duration
© www.soinside.com 2019 - 2024. All rights reserved.