Aba*_*cus 8 performance sql-server delete sql-server-2012 blob
我有一个用于记录的表和一个用于清除DELETE 性能非常慢的旧数据的存储过程,这超出了我的理解。我正在寻找如何修改表或 DELETE 语句以在 LOB 数据上表现得相当好。或者,如果微软确认了这个问题——比如“我们已经用 SQL 服务器版本 x 解决了这个问题”,或者甚至“我们看到这性能很差,但它不是优先事项”——这也可以.
这是在 Microsoft SQL Server 2012 (SP3) 上运行的。下面基本上是我的实际表格和代码,只是稍微简化了:
CREATE TABLE [LOG_VALUE](
[ID] [int] IDENTITY(1,1) NOT NULL,
[VALUE] [varchar](max) NOT NULL,
[CHECKSUM] [int] NOT NULL,
[VALUE_LEN] [int] NOT NULL,
CONSTRAINT [PK_LOG_REQUEST] PRIMARY KEY CLUSTERED ([ID] ASC)
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
Run Code Online (Sandbox Code Playgroud)
有问题的删除是通过以下方式完成的:
WHILE (@@ROWCOUNT > 0)
DELETE TOP (100) [LOG_VALUE]
OUTPUT DELETED.[VALUE_LEN] INTO @DELETED_ROWS
WHERE [ID] IN (SELECT [ID] FROM @DELETE_IDS);
Run Code Online (Sandbox Code Playgroud)
基本的存储过程流程是:
显然,LOB 数据必须加载到服务器的内存中才能删除。支持:1)当我在表中插入 12000 行时,它几乎可以是瞬间 2)检索 12000 行几乎是瞬间 3)一旦它们不再在缓存中,选择和删除相同的 12000 行都需要大约 40秒。
我能找到的最相关的问题是:https : //serverfault.com/questions/241893/delete-performance-for-lob-data-in-sql-server 从 2011 年开始,但遗憾的是没有令人满意的答案。我只是希望在 dba.stackexchange.com 上提出这个问题会找到更多知识渊博的观众:)。该问题的作者肯定比我更了解这一点,但当我阅读它时,中心点是:
似乎这种释放应该在清理任务中发生,而不是预先发生。由于在谓词(或 OUTPUT)中没有引用 LOB 数据,因此根本不需要将其加载到缓存中。
更多可能相关的信息,但我认为不是:
READ_COMMITTED_SNAPSHOT并且ALLOW_SNAPSHOT_ISOLATION都关闭。除了删除/更新 LOB 数据外,整个数据库(以及同一服务器上的其他数据库)在所有情况下的表现都符合我的预期。
...一旦它们不再在缓存中,选择和删除相同的 12000 行都需要大约 40 秒。
这似乎表明存储子系统不足。如果这是原因,SQL Server 可能会使用其中一种PAGEIOLATCH_XX等待类型进行等待。
显然,LOB 数据必须加载到服务器的内存中才能删除。
正如 Paul Randal 所说(更新 2,在您链接的问题中),SQL Server必须遍历 LOB 树才能找到必须删除的页面。为此,SQL Server 需要将这些 LOB 树页放入内存中。真的没有办法解决这个问题。该信息无法以任何其他方式获得。
似乎这种释放应该在清理任务中发生,而不是预先发生。
这种工作方式没有很好的记录。
在我的测试中,如果没有特殊原因保留该行,SQL Server 会立即删除 LOB 数据。这似乎是一种优化:毕竟,如果我们已经接触到 LOB 数据,我们不妨趁着还手把它删除掉。将它推迟到幽灵清理 (GC) 只会增加开销,因为 GC 还需要遍历链。此外,日志记录也减少了,因为 SQL Server 只需要记录解除分配,而不是完整的 LOB 内容。
如果(例如)表上有触发器,或者如果启用了行版本控制隔离级别,则LOB 删除操作将推迟到GC。这两个功能都使用行版本,必须在 LOB 行上维护行版本。在这些情况下,LOB 删除被完全记录。当 GC 稍后运行时,它会执行 LOB 页的释放。可以使用(记录在案的)全局跟踪标志 661暂时禁用 GC ,如果您想自己测试,可以查看这些幻影 LOB 记录。
鉴于所有这些,很难看出(完全)记录删除并推迟重复已经完成的大部分相同工作到 GC 会对您有所帮助。在删除期间记录更少并删除 LOB 数据可能会更快。
除了存储系统不堪重负/指定不足的可能性之外,问题中没有足够的内容来推测您删除性能不佳的确切原因,但我可以说,总的来说,最好是:
有关第 1 点的更多信息,请参阅Paul Randal 的性能错误:涉及行外 LOB 数据的NOLOCK 扫描。有关第 2 点和第 3 点的更多信息,请参阅删除拆分页面和转发的重影(由我撰写)。
同样可能是简化的示例遗漏了一个关键细节,或者表变量产生了低效的执行计划,或者您的表已经有数十亿条幽灵 LOB 记录。详细的分析可能需要访问系统本身。
| 归档时间: |
|
| 查看次数: |
2099 次 |
| 最近记录: |