2013-05-22 53 views
0

我试图从数据库中清除大于13个月的任何数据的大量历史数据。从SQL Server数据库删除大量数据

我写了一个存储过程截断,但是当我尝试运行它们时,我有两个问题。

问题1-删除填满数据库事务日志并在磁盘驱动器空间不足时崩溃数据库。

问题2 - 脚本本身需要很长时间才能执行。

以下是在SP的陈述:

DELETE FROM Header_Table WHERE Date_DT < @date 

Header_Table表具有与其他10代表一个ON DELETE CASCADE关系。这意味着,当我通过Header_Table

  1. 从10桌参考启动它删除从Header_Table表中的数据上面的查询,以及而在第二份声明,我从​​表插入数据到临时表。

    INSERT INTO Temp_Table (Key, AccNum, Exp, Name_VC) 
        SELECT 
         in.Key AS CRD_NFO_CIK, 
         in.Acct_Num AS CRD_NFO_ACC, 
         in.Exp AS CRD_NFO_EXP, 
         in.Name_on_Card_VC AS CRD_NFO_NAME  
        FROM 
         Information_Table in 
        LEFT OUTER JOIN 
         Card_T crd ON in.Key = crd.Card_Info_Key 
        LEFT OUTER JOIN 
         Business_T business ON in.Key = business.CC_Info_Key 
        LEFT OUTER JOIN 
         Con_T contr ON in.Key = contr.Card_Info_Key 
        LEFT OUTER JOIN 
         Customer_Payment_T customer ON in.Key = customer.Card_Info_Key 
        LEFT OUTER JOIN 
         Temp_Table Temp ON in.Key = Temp.Key 
        WHERE 
         Temp.Key IS NULL AND 
         crd.Card_Info_Key IS NULL AND 
         business.CC_Info_Key IS NULL AND 
         contr.Card_Info_Key IS NULL AND 
         customer.Card_Info_Key IS NULL 
    
  2. 在下面的语句中,我其实从Information_Table删除数据

    DELETE info 
    FROM Information_Table in  
    LEFT OUTER JOIN Card_T crd ON in.Key = crd.Card_Info_Key  
    LEFT OUTER JOIN Business_T business ON in.Key = business.CC_Info_Key  
    LEFT OUTER JOIN Con_T contr ON in.Key = contr.Card_Info_Key  
    LEFT OUTER JOIN Customer_Payment_T customer ON in.Key = customer.Card_Info_Key 
    WHERE 
        crd.Card_Info_Key IS NULL AND 
        business.CC_Info_Key IS NULL AND 
        contr.Card_Info_Key IS NULL AND 
        customer.Card_Info_Key IS NULL 
    
+1

“Header_Table表与其他10个表具有ON DELETE CASCADE关系。” - 这肯定会*花费大量的时间用于该表上的任何删除操作。如果您手动删除每个表中的(批次)记录,您可能会获得更多性能。 – JimmyB

+0

@HannoBinder实际上我们并没有意识到10个表的进一步CASCADE'ing关系。由于这是客户生产数据库,因此我们不能冒很大风险手动删除表格记录。 –

+0

嗯,太糟糕了。考虑到事务日志[this](http://databases.about.com/od/sqlserver/a/truncate_shrink.htm)可能会有所帮助。 - 删除*批次中的记录*将是无论如何要走的路,这也让您可以控制操作运行多久而不会中断;您可能需要批量生产4周的数据,并且每天晚上删除其中一个批次,直到您赶上餐桌的增长。不要忘记在每批之后“提交”(至少)释放任何锁并允许事务日志收缩。 – JimmyB

回答

2

在这种情况下,你应该总是在chunks.What我的建议是,删除数据删除数据分批。

+0

这对于不增长事务日志文件来说看起来不错,但它需要花费相同的时间来执行这些sql。 –

+0

是的,但它是实现这一目标的安全和最佳途径。 – AnandPhadke

+0

我同意。每当我必须这样做时,我会一次删除块。使用删除顶部#... 至于事务日志填满了,除了将恢复模式从完全更改为简单之外,我知道没有办法绕过它,我强烈建议不要这样做。 只要记住转换日志在那里,所以你可以得到的变化回来。你基本上在这方面努力。 你能否在系统安静地转换到简单模式时执行删除操作,然后再变回完整状态? –

0

备份事务日志的频率如何?如果您在批次中删除批处理,那么经常进行事务日志备份应该可以防止事务日志填满,除非您的系统没有设置为备份(或仅在不适当的时间表中才这样做)。注意事务日志备份与数据库备份完全不同,应该在事务性系统中频繁发生 - 我们每15分钟备份一次。另外,因为你有级联删除(我个人绝不允许),你可能需要一个相当小的批次。