SQL Server - 使用相同SELECT结果运行两个DELETE语句的最佳方式

时间:2018-04-11 16:35:13

标签: sql sql-server

我需要使用从唯一ids查询中找到的一些SELECT来删除两个表中的条目。

使用SQL Server执行此操作的最佳方法是什么?

我目前使用Table Variable

DECLARE @emailIdsToDelete TABLE(id int NOT NULL);

INSERT INTO @emailIdsToDelete
SELECT id
FROM ...;

DELETE organisations_emails
FROM @emailIdsToDelete etd
INNER JOIN ...;

DELETE emails
FROM @emailIdsToDelete etd
INNER JOIN ...;

但是因为我需要该表只存储SELECT的结果,并且仅针对此特定查询的范围,我想知道是否有更高性能的解决方案。

我想我不能使用CTE(使用“with()”子句)因为它只允许一个以下语句,而不是两个。

有没有办法从这两个表中删除,而不必先创建临时表?某种join?或者我的解决方案是否已经达到最优?

更新:假设这些表之间没有“ON DELETE CASCADE”。

2 个答案:

答案 0 :(得分:1)

另一种方法是在organisations_emailsemails之间设置ON DELETE CASCADE的外键。然后您只需要从emails删除,organisations_emails中的匹配行将自动删除。

当然,假设外键适合您的架构。

答案 1 :(得分:1)

Cascade Delete是一个选项,但是您需要进行测试以验证它是否更具性能,有时即使使用FK也可以留下孤儿记录。

Soft Delete您可以添加isDeleteFlag列,将其设置为bit default(0),并在运行查询时将其更新为1,再次必须对其进行测试。如果你想停在那里,你需要更改你的usp_以适应不返回这些记录。 where isDeleteFlag = 0

要跟进最高性能,您可以使用软删除,然后在晚上进行较小批量的删除,或者您可以将删除ID存储在单独的表中,并在晚上批量删除它们。这可能对你有用,取决于你想要完成什么,如果可以在晚上而不是在正常的业务操作中窃取性能,有时它是不可行的。

最后,答案取决于里程数和里程数会有所不同,您需要测试解决方案以比较性能。

您可以选择使用您的方法并使用变量表/临时表或用户定义的表类型。

编辑:您还可以在事务中输出已删除的ID和菊花链删除。