每周一次,在过去 5 周内,大约在一天中的同一时间(清晨,可能基于人们开始使用它时的用户活动),SQL Server 2016(AWS RDS,镜像)开始超时很多查询。
所有表上的 UPDATE STATISTICS 总是立即修复它。
在第一次之后,我让它每晚(而不是每周)更新所有表上的所有统计信息,但它仍然发生了,(更新统计信息运行后大约 8 小时,但不是每天运行)。
这最后一次,我启用了查询存储,看看我是否能找到它是哪个特定的查询/查询计划。我想我可以将其缩小为一个:
找到该查询后,我添加了一个推荐索引,该索引在这个不常用的查询中缺失(但它确实触及了很多常用表)。
错误的查询计划正在执行索引扫描(在只有 10k 行的表上)。其他以毫秒为单位返回的查询计划,虽然用于执行相同的扫描。最新的查询计划,在创建新索引后只查找。但即使没有该索引,99% 的情况下,它也会在几毫秒内返回,但是,每周需要超过 40 秒。
这是从 2012 年迁移到 SQL Server 2016 后开始发生的。
DBCC CHECKDB 没有返回错误。
我刚刚添加的索引:
CREATE NONCLUSTERED INDEX idx_AppointmetnAttendee_AttendeeType
ON [dbo].[AppointmentAttendee] ([UserID],[AttendeeType])
CREATE NONCLUSTERED INDEX [idx_appointment_start] ON [dbo].[Appointment]
(
[ProjectID] ASC,
[Start] ASC
)
INCLUDE ( [ID],
[AllDay],
[End],
[Location],
[Notes],
[Title],
[CreatedByID]) WITH (PAD_INDEX = OFF, …Run Code Online (Sandbox Code Playgroud) sql-server statistics execution-plan sql-server-2016 query-store
如果在可用性组中的主节点上强制执行计划,它是否应用于在辅助节点上运行的查询?
我正在寻找涵盖计划强制两种可能性的答案:
我已阅读以下内容,这些内容表明 QS 强制计划不会结转,但在文档中找不到任何权威信息,或任何有关计划指南的信息。
强制的决定性证据是辅助节点的执行计划中存在Use Plan或PlanGuideName和PlanGuideDB属性。
sql-server execution-plan availability-groups query-store plan-guides
查询存储强制计划功能似乎没有执行该计划。
我知道Query Store - Forced 并不总是意味着 Forced;然而,我的计划可能不会发生微不足道的变化,但查询优化器可能会继续选择不正确的索引、循环选择等。
基本上:它不尊重我被迫的计划选择。我强迫了很多计划,但它根本行不通。
sys.query_store_plan force_failure_count.query_store_plan_forcing_failed不会产生任何结果。0 事件。例如,在 20.09 强制执行的计划。只有 1 个编译碰巧使用了强制计划。
计划大相径庭,一个使用带有 INDEX 1 的 Hash Match join,另一个使用带有 INDEX 2 的 Loop Join。
版本:Microsoft SQL Server 2016 (SP1-GDR) (KB3210089) - 13.0.4202.2 (X64)
我在这里缺少什么?
SQL Server 2016 中引入的新查询存储很棒。它很好地替代了我以前使用旧的 Profiler 工具所做的大部分工作。但是,我还没有找到一种方法来捕获与对它嗅出的高资源消耗查询的单个调用相关联的参数值。这可能吗?
我知道查询存储更多地处理聚合数据而不是单个调用,所以我怀疑我在这里可能不走运。当我发现一个缓慢的查询时,我发现将参数与其最慢的调用之一关联起来也很方便进行故障排除。我想知道如何使用最新最好的工具来做到这一点。(我不会错过使用 Profiler!)
在安全方面,查询存储比 Profiler 更容易锁定吗?我认为它需要从某个级别的单个调用中捕获数据才能计算聚合。只是不确定它是否存储了其中的任何一个。
performance sql-server sql-server-2016 query-store query-performance
我从一开始说,我的问题/问题类似于此之前的一个,但因为我不知道的原因或起始信息是一样的,我决定后,我的问题有一些更多的细节。
手头问题:
初步调查:
有罪查询:
Select qt.query_sql_text,
q.query_id,
qt.query_text_id,
rs1.runtime_stats_id AS runtime_stats_id_1,
interval_1 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi1.start_time),
p1.plan_id AS plan_1,
rs1.avg_duration AS avg_duration_1,
rs2.avg_duration AS avg_duration_2,
p2.plan_id AS plan_2,
interval_2 = DateAdd(minute, -(DateDiff(minute, getdate(), getutcdate())), rsi2.start_time),
rs2.runtime_stats_id AS runtime_stats_id_2
From sys.query_store_query_text AS qt
Inner Join sys.query_store_query AS …Run Code Online (Sandbox Code Playgroud) 什么是 SQL 的“不可提及的词”?
我正在阅读sys.query_store_query_text (Transact-SQL)并且我看到以下内容,所以我谷歌了 {SQL "unmentionable" word}
has_restricted_text
bit
查询文本包含密码或其他不可提及的词。
除了 3 个将我带回到我找到它的位置的链接之外,我没有找到任何似乎显示与密码或 SQL 可能关心的任何关系的内容。
我一直在深入研究 SQL Server 查询存储,我经常看到对“临时”查询的引用。但是,我还没有看到查询存储确定临时查询是什么。我见过一些地方,它可以被推断为不带参数的查询或只执行一次的查询。是否存在对此的正式定义?我不是说一般。我的意思是因为它与查询存储有关。
例如,此页面显示了从查询存储中删除临时查询的示例,但它使用的条件似乎只是执行计数为 1。这似乎是临时查询的奇怪定义。顺便说一句,如果您转到该页面,请搜索“删除临时查询”。
以下是查询存储遇到的性能问题的简化:
CREATE TABLE #tears
(
plan_id bigint NOT NULL
);
INSERT #tears (plan_id)
VALUES (1);
SELECT
T.plan_id
FROM #tears AS T
LEFT JOIN sys.query_store_plan AS QSP
ON QSP.plan_id = T.plan_id;
Run Code Online (Sandbox Code Playgroud)
该plan_id列被记录为 的主键sys.query_store_plan,但执行计划并不像预期的那样使用连接消除:
plan_id不能复制临时表中的行LEFT JOIN,因此无法T消除from中的任何行。为什么会这样,在这里可以做些什么来消除连接?
performance join sql-server execution-plan query-store query-performance
对 SQL 系统数据库(master、model、msdb、tempdb)的查询存储只能在 msdb 上使用。我查看并没有在 msdb 上找到任何有关查询存储的文档。
虽然您无法在 GUI 中看到它,但可以在您的 SQL 2016 实例上对其进行验证
验证查询存储已关闭
USE msdb
SELECT * FROM sys.database_query_store_options;
Run Code Online (Sandbox Code Playgroud)
打开查询存储
USE [master]
GO
ALTER DATABASE msdb SET QUERY_STORE = ON
GO
ALTER DATABASE msdb SET QUERY_STORE (OPERATION_MODE = READ_WRITE
, INTERVAL_LENGTH_MINUTES = 30
, MAX_STORAGE_SIZE_MB = 1000
, QUERY_CAPTURE_MODE = AUTO)
GO
Run Code Online (Sandbox Code Playgroud)
验证查询存储已开启
USE msdb
SELECT * FROM sys.database_query_store_options;
Run Code Online (Sandbox Code Playgroud)
在所有系统数据库中,为什么 msdb 是唯一一个可以选择使用查询存储的数据库,它增加了什么价值?
-- Stop Query Store
USE [master]
GO
ALTER DATABASE msdb SET QUERY_STORE = OFF
GO
Run Code Online (Sandbox Code Playgroud) 我最近将我们的 2016 SQL Server 更新到 SP2 和 2018 年 8 月发布的最新 CU (KB4458621)。就在最后一天左右,我注意到我有一些阻塞。我无法杀死 SPID b/c,它不是用户进程。根据 SP_WHO2,命令是“Query Store ASYN”。我尝试通过脚本和 UI 清除数据并禁用查询存储。似乎没有任何效果,它只是旋转,然后开始造成更多阻塞。还有其他人有这个问题吗?谁能帮我弄清楚如何成功禁用查询存储?SP_WhoIsActive @show_System_SPIDS = 1 个结果如下(仅查询存储结果)
更新 - 这现在导致 TempDB 驱动器填满。几个小时后尝试重新启动,看看是否能解决问题。将及时向大家发布。
谢谢,内特
query-store ×10
sql-server ×9
performance ×2
statistics ×2
blocking ×1
join ×1
msdb ×1
plan-guides ×1