sql - 优化 DELETE 查询,其中行包含大数据(以 Base64 序列化的文件)
问题描述
当要删除大量行时,有许多关于优化 DELETE 查询的有用技巧。但是,在我的情况下,它并不算多(约 3-4000 行),但每一行都包含在 Base64 中序列化的文件的字段。它们中的大多数都在 10 MB 以上,但也有少数超过 100 MB。DELETE 查询需要 1 个多小时才能完成。有什么技巧可以让它显着加快速度吗?
我尝试过批处理,但由于某种原因实际上使情况变得更糟(更糟的几个小时)。
我暂时禁用了所有约束(ALTER TABLE ? NOCHECK CONSTRAINT all
在每个表上),它帮助了大约 10-20 分钟,但它仍然非常缓慢。
我的查询如下所示:
DECLARE @OrphanedIds TABLE (DocumentId int);
INSERT INTO @OrphanedIds
SELECT DocumentId
FROM Table2
WHERE ContentType = 'Something';
DELETE FROM Table2 WHERE DocumentId IN (SELECT DocumentId FROM @OrphanedIds);
DELETE FROM Table1 WHERE Id IN (SELECT DocumentId FROM @OrphanedIds);
请注意,Table2 包含 Table1 ( ) 的外键Table2.DocumentId = Table1.Id
,但如上所述,我暂时禁用了约束。
解决方案
首先,使文档 id 成为表中的主键:
DECLARE @OrphanedIds TABLE (DocumentId int PRIMARY TABLE);
然后使用EXISTS
(or JOIN
) 而不是IN
:
DELETE FROM Table2
WHERE EXISTS (SELECT 1 FROM @OrphanedIds o WHERE table2.DocumentId = o.DocumentId);
DELETE FROM Table1
WHERE EXISTS (SELECT 1 FROM @OrphanedIds o WHERE table1.DocumentId = o.DocumentId);
您可能会发现级联删除外键可以使数据保持同步——如果您想在将来确保这一点。
推荐阅读
- python - Python排序二维列表
- group-by - 将连续月份分组在一起以对 HIVE 中的数据进行分类
- r - 如何从R中的文件名中提取年份
- spring-boot - SpringBoot 在 DataSourceAutoConfiguration 之前执行自定义配置
- java - 使用 Angular 5 (REST Webservices) 生成服务器端会话
- powershell - 带有 ScriptBlock 的 Group-Object 的意外行为
- android - 缺少 Google 应用 ID
- node.js - 如何使用 ssl 在同一个域名上运行 api 和网站
- powershell - 从字符串中选择 Var
- javascript - 如何在 ExtJS 中动态改变组件的可见性