我们的 SQL Server 2014 数据库事务日志之一增长非常快,我找不到其根本原因。
数据库处于简单恢复模式。在完整备份期间,日志文件增长到其限制 (800GB) 并且备份失败。
我在备份期间检查了事务,并没有发现任何异常。
所有事务都是我们的常规加载,没有维护工作(索引重建等)
我知道备份可以防止日志重用,但这意味着在备份期间会有 800GB 的更改,这没有任何意义。
我将这个数据库与类似的数据库大小、加载和备份持续时间进行了比较。第二个数据库日志的增长不超过 400GB。
数据库大小为 7TB。备份时间约为 20 小时。日志增长的唯一时间是在备份期间。Log_reuse 显示正确的 Backup_Restore。没有长时间运行的事务。
问题是日志增长的“速度” - 与具有相同负载和相同备份持续时间的类似站点相比,日志少了 4 倍。
我面临 SQL Server 生成非最佳执行计划的问题:嵌套循环连接并寻找维度表并对其执行 2M 读取。
排序操作估计是 100 行而不是 450 K 行,可能会影响计划选择:
NestedLoop:https ://www.brentozar.com/pastetheplan/ ? id = B110MZ2Pm或 NestedLoop 计划
这是在测试数据库中。我们有一个具有相同架构和几乎相同数据的附加数据库。
运行完全相同的查询(均来自 SSMS)使用哈希联接和维度表扫描(32K 读取)生成不同的计划:
HashJoin:https ://www.brentozar.com/pastetheplan/ ? id = r1Jm7b2D7或 哈希计划
我需要帮助来理解和解决问题。
我可以通过提示 Hash Joint 来解决这个问题,但是同一实例上的 2 个相似的 DB 生成不同的计划没有任何意义。
更新 #1:我发现估计的成本是不同的所以当 SQL Server 并行执行时,它会选择一个散列连接。
用单线程会嵌套循环。
更新 #2:在从同一个表中进行 SELECT 时发生了同样的问题。取决于列数(估计成本)。当我减少列数时,执行计划陷入嵌套循环并寻找维度表。
在我们的一台生产服务器上,我发现索引大小是数据大小的 10 倍。
这些服务器和模式与类似的工作负载相同。
CREATE TABLE [dbo].[process_aggregation_close]
(
[organization_id] [bigint] NOT NULL,
[computer_id] [uniqueidentifier] NOT NULL,
[process_id] [int] NOT NULL,
.
.
INDEX [ix_process_aggregation_memory_computer_id_process_id] NONCLUSTERED
(
[organization_id] ASC,
[computer_id] ASC,
[process_id] ASC
)
)WITH ( MEMORY_OPTIMIZED = ON , DURABILITY = SCHEMA_ONLY )
GO
Run Code Online (Sandbox Code Playgroud)
表是临时表,它们涉及非常频繁的插入/删除操作。
Microsoft SQL Server 2017 CU9 标准版。
所有数据库都处于完全恢复模式。我认为它与checkpoint无关,因为这些表仅是模式持久的。(无论如何,我尝试了一个没有效果的手动检查点)。
这些内存表是暂存的,并且总是存在插入和删除活动。我监控了五个负载相似的 SQL Server。此行为仅发生在一个上。