2

下面是我可能会运行的查询示例,对于每个类别,我希望 NumberOfCourses 不仅代表该特定类别,还代表其下的任何子类别。我认为该查询是相当不言自明的。

select  c.CategoryID, courses.MarketID, count(distinct courses.CourseID) NumberOfCourses
from    Category c
        join CategoryHierarchy tch on tch.HierarchyKey like '%~' + cast(c.CategoryID as varchar) + '~%'
        join vLiveEvents courses on tch.CategoryID = courses.CategoryID
where   courses.MarketID is not null
group by c.CategoryHumanID, courses.MarketID

当我按原样运行时,它可能需要将近两分钟,但是如果我添加提示Option (Force Order),则只需几秒钟即可运行。所以我的问题是我做错了什么导致 SQL 创建一个糟糕的计划,还是 SQL 引擎实际上不擅长优化这样的层次结构连接?

我尝试包括 sql 计划,但它太长了,所以不会让我有那么多字符。我很乐意分享它,但如果有人能告诉我怎么做的话。

编辑:我想可能不是每个人都知道这些层次结构是如何工作的。它们的层次结构键看起来像 ~1234~5678~9123~ 其中 1234 是 5678 的父级,而 5678 是 9123 的父级。通过对 CategoryID 进行类似比较,我可以在结果中包含所有子类别。

4

1 回答 1

1

从 SQL Server 2016+ 开始,引入了查询存储功能来监控性能。它提供了对查询计划选择和性能的洞察。

它还提供了强制计划的选项。

它不是跟踪或扩展事件的完全替代,但随着它从一个版本到另一个版本的演变,我们可能会在 SQL Server 的未来版本中获得一个功能齐全的查询存储。Query Store 的主要流程

  1. SQL Server 现有组件通过使用查询存储管理器与查询存储交互。
  2. 查询存储管理器确定应该使用哪个存储,然后将执行传递给该存储(计划或运行时统计或查询等待统计)
    • 计划存储 - 保存执行计划信息
    • Runtime Stats Store - 保存执行统计信息
    • Query Wait Stats Store - 持久化等待统计信息。
  3. 计划、运行时统计和等待存储使用查询存储作为 SQL Server 的扩展。

在此处输入图像描述

  1. 启用查询存储:查询存储在服务器上的数据库级别工作。

    • 默认情况下,查询存储对新数据库不活动。
    • 您不能为主数据库或tempdb数据库启用查询存储。
    • 可用车管所

      sys.database_query_store_options(事务处理 SQL)

  2. 在查询存储中收集信息:我们使用查询存储 DMV(数据管理视图)从三个存储中收集所有可用信息。

注意:查询等待统计存储仅在 SQL Server 2017+ 中可用

于 2018-06-02T21:49:16.950 回答