在过去的5周中,大约每天的同一时间(清晨,可能取决于人们开始使用时的用户活动),每周一次,SQL Server 2016(AWS RDS,已镜像)开始超时查询。
所有表上的UPDATE STATISTICS始终会立即对其进行修复。
第一次之后,我让它每晚(而不是每周)更新所有表上的所有统计信息,但是仍然发生(更新统计信息运行后大约8小时,但并非每天运行)。
上一次,我启用了查询存储,以查看是否可以找到具体的查询/查询计划。我想我可以将其缩小到一个:
找到该查询后,我添加了一个推荐索引,该索引在此不常用的查询中丢失了(但它确实涉及很多常用表)。
错误的查询计划正在执行索引扫描(在只有1万行的表上)。不过,其他返回的查询计划(以毫秒为单位)也用于进行相同的扫描。创建新索引后,最新查询计划仅查找。但是,即使没有该索引,也有99%的时间在几毫秒内返回了索引,但是每周要花40秒以上的时间。
- 超时的坏消息:http : //brentozar.com/pastetheplan/?id=rymaWt56e
- 以前不会超时的计划:http : //brentozar.com/pastetheplan/?id=HyN7ftcpe
- 具有新索引的最新计划:http : //brentozar.com/pastetheplan/?id=ryLuGKcag
从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, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
完整查询文字:
https://pastebin.com/Z5szPBfu(由LINQ生成,我可以/应该能够优化所选的列,但是与该问题无关)