从大表引用的小表中删除

时间:2012-04-03 20:17:10

标签: sql sql-server performance sql-delete

想象一下跟踪客户之间付款的数据库。

说我有一张顾客表:

Customer 
----------
CustomerID
Name

和一个交易表

Transaction
------------
BuyerID
SellerID
Amount

其中,BuyerID和SellerID都是Customer表的CustomerID列的外键引用。

在我当前(类似的)情况下,即使Customer表很小(2000行),Transaction表也很大(5亿行)。但是,从Customer表中删除一行需要很长时间,因为数据库必须扫描Transaction表以查看Customer是否有任何引用事务(实际上,它必须执行两次 - 一次检查是否为BuyerID)和一个卖家ID)。在TransactionID或SellerID上没有对Transaction表进行索引(真实表是在买方,卖方和其他一些列的组合上编制索引)

我知道我可以删除所有外键约束,删除行,然后重新添加约束。这会比启用外键的DELETE FROM更快吗?有没有其他方法可以加快我缺少的删除操作。

4 个答案:

答案 0 :(得分:4)

您应该在BuyerID表中为SellerIDTransaction编制索引...

有关为什么要将外键编入索引的进一步说明read Kimberly Tripp's excellent article on the subject

答案 1 :(得分:1)

继续添加额外的两个索引。 只留下限制。

答案 2 :(得分:1)

通常,如果我有客户的销售交易,我不想删除它们或客户。这正是您具有外键约束的原因,因此您不会删除客户。这只是搞乱你的财务报告(为什么2011年的销售额突然下降了20%,我们从数据库中删除了一些记录,而不是很好的对话。)。你想要的是让客户不活动,通常在这种情况下不删除它们。

鉴于Ryan说这是一个正在开发的数据库,而不是生产中,因为我们可能会同时向其输入数据,我会删除FK,将我打算删除的客户ID放入工作表中然后删除父表和所有子表。这样,如果需要,您可以批量删除5亿行表。然后当你完成后重新开启FK。

答案 3 :(得分:0)

如果我正在使用5亿行,我要做的第一件事是 - 删除外键引用并集中存储过程以控制删除功能。