每周一次,在过去 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
CACHESTORE_SQLCP Sql 计划在几天后占用 > 38 GB。
我们已经在运行“优化临时工作负载”选项。(实体框架和自定义报告创建了很多临时!)
具有多可用区镜像的 AWS RDS 上的 SQL Server 2016 SE 3.00.2164.0.v1
当我运行时:
DBCC FREESYSTEMCACHE('SQL Plans');
Run Code Online (Sandbox Code Playgroud)
或者
DBCC FREEPROCCACHE
Run Code Online (Sandbox Code Playgroud)
或者
DBCC FREESYSTEMCACHE ('SQL Plans') WITH MARK_IN_USE_FOR_REMOVAL
Run Code Online (Sandbox Code Playgroud)
或者
DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;
Run Code Online (Sandbox Code Playgroud)
它似乎没有清除它:
SELECT TOP 1 type, name, pages_kb FROM sys.dm_os_memory_clerks ORDER BY pages_kb desc
type name pages_kb
CACHESTORE_SQLCP SQL Plans 38321048
Run Code Online (Sandbox Code Playgroud)
我在启用查询存储的情况下运行,但我禁用了它以查看是否有任何干扰,它似乎没有帮助,但我将其关闭。
真正奇怪的是
SELECT COUNT(*) FROM sys.dm_exec_cached_plans
Run Code Online (Sandbox Code Playgroud)
是 1-3 左右(它似乎只显示显示当前正在运行的查询),即使所有内存都已保留,甚至在我尝试清除任何内容之前。我错过了什么?
CACHESTORE_SQLCP 占用了所有可用内存的 60% 以上,这是一个问题,因为偶尔会发生内存等待。此外,我们不得不在周末终止一个持续 4 小时的例行 DBCC CHECKDB,因为内存不足导致等待(它立即完成,没有错误,打开 PHYSICAL_ONLY)。
有没有办法回收这些内存(除了每晚重启!?)?
当我跑
SELECT * FROM …Run Code Online (Sandbox Code Playgroud)