有没有比使用CTE更快的方式在SQL Server数据库之间移动数据行?

时间:2015-03-25 16:50:10

标签: sql sql-server database archive maintenance

我在SQL Server 2012 Express上使用以下查询将一个[主]数据库中超过4天的数据移动到另一个[辅助数据库]中以进行存档。唯一的问题是,这会使数据库脱机,因为它通常会移动大约500k行数据,并且随着更多数据点被添加到数据库,这个数字正在攀升。结果是我的基于Web的应用程序无法访问数据库(大多数情况下)大约2个小时,这会拖延很多其他进程以及应用程序。

DECLARE @4daysago datetime
SELECT @4daysago = DATEADD(d, -4, GetDate());

SET IDENTITY_INSERT [activetrackarchivedb].dbo.[Data Import] ON;

--Transfer from current (production) DB to Archive DB
WITH CTE as (
    SELECT TOP 1000000 *
    FROM [activetrackdb].dbo.[Data Import] 
    WHERE [activetrackdb].dbo.[Data Import].[Receive Date] < @7daysago
    ORDER BY [Receive Date] ASC)
DELETE CTE
  OUTPUT DELETED.id, 
  DELETED.[Company id], 
  DELETED.[Site id],
  DELETED.[Site name],
  DELETED.[Receive date],
  DELETED.[Detect date],
  INTO  [activetrackarchivedb].dbo.[Data Import] 
  (id, 
  [Company id], 
  [Site id],
  [Site name],
  [Receive date],
  [Detect date]);

我可以使用更好的方法来“转移”这些行吗?即使新方法较慢,如果它至少仍然允许访问数据库。这个花了我一个星期来实现(我是一个新手)并参与了StackOverflow社区的帮助。到目前为止一直很好,但随着数据量的增加,它变得非常繁琐。

这也不是用于备份目的。传输行的数据库只具有更高的容量,并且存档数据仍然在生产环境中使用(它只是使主数据库在与其他维护和索引脚本结合使用时更易于维护和响应)

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

在SSIS(2008)和许多其他地方,SQL Server默认行数大小为10000.您可能希望一次尝试行的大小,但我怀疑较小的大小可能最终会执行快得多。

答案 1 :(得分:0)

为什么不运行这样的事情(假设表格具有相同的字段):

SET IDENTITY_INSERT [activetrackarchivedb].dbo.[Data Import] ON;

DELETE FROM [activetrackdb].dbo.[Data Import]
OUTPUT DELETED.* INTO  [activetrackarchivedb].dbo.[Data Import] 
WHERE [activetrackdb].dbo.[Data Import].[Receive Date] < DATEADD(DAY,-4,GETDATE())

我不明白为什么这需要花费的时间超过一分钟,而且可能要比这少得多。对于SQL Server来说,500k行并不是那么多。在我的笔记本电脑上完成与该行数相似的语句大约需要5秒钟。

答案 2 :(得分:0)

根据您的评论,CTE似乎没必要。您可以使用更简单的查询来完成此任务。

DELETE FROM [activetrackdb].dbo.[Data Import]
  OUTPUT 
      DELETED.id, 
      DELETED.[Company id], 
      DELETED.[Site id],
      DELETED.[Site name],
      DELETED.[Receive date],
      DELETED.[Detect date]
  INTO  [activetrackarchivedb].dbo.[Data Import] 
      (id, 
       [Company id], 
       [Site id],
       [Site name],
       [Receive date],
       [Detect date]) 
WHERE [Receive Date] < @7daysago