全部删除/批量插入

时间:2010-10-26 14:33:38

标签: sql sql-server sql-server-2005 performance bulkinsert

首先请允许我说我在SQL Server 2005上运行,因此我无法访问MERGE

我有一个约150k行的表,我每天都会从文本文件中更新。当行从文本文件中删除时,我需要从数据库中删除它们,如果它们发生变化或者是新的,我需要相应地更新/插入。

经过一些测试后,我发现性能明智的是,执行完全删除然后从文本文件批量插入而不是通过执行更新/插入的行逐行读取是指数级更快。但是,我最近发现了一些帖子,讨论使用临时表和MERGE语句的输出来模仿SQL Server 2008的UPDATE功能。

我对此感兴趣,因为我正在调查当表没有行时如何消除删除/批量插入方法中的时间。我仍然认为这种方法最快,所以我正在寻找解决空表问题的最佳方法。

由于

5 个答案:

答案 0 :(得分:5)

我认为你最快的方法是:

  1. 删除所有外键和索引 从你的桌子。
  2. Truncate你的     表
  3. 批量插入数据。
  4. 重新创建您的外键和 索引。

答案 1 :(得分:3)

问题是Joe的解决方案不够快,或者在您的流程运行时您无法对目标表进行任何活动?如果您只需要阻止用户针对目标表运行查询,则应在事务块中包含您的进程。这样,当您的TRUNCATE TABLE执行时,它将创建一个表锁,该锁将在事务持续期间保持,如下所示:

begin tran;

truncate table stage_table

bulk insert stage_table
from N'C:\datafile.txt'

commit tran;

答案 2 :(得分:1)

另一种解决方案,可以满足您对正在更新的表没有“停机时间”的要求。

听起来你最初是在阅读文件并一次执行INSERT / UPDATE / DELETE 1行。一种比这更有效的方法,不涉及清理表格如下:

1)将文件批量加载到一个新的,单独的表中(无索引)
2)然后在其上创建PK 3)运行3个语句以从这个新的(临时)表更新原始表:
删除主表中新表中不存在的行
更新主表中的行,其中新表中有匹配的行 从新表中将行插入到主表中它们尚不存在

这将比逐行操作表现更好,并且有望满足您的整体要求

答案 3 :(得分:1)

有一种方法可以在零停机时间内更新表:在表中保留两天的数据,并在加载新行后删除旧行

  1. 添加一个DataDate列,表示~150K行有效的日期。
  2. 使用“今天的”DataDate创建一行一列表。
  3. 创建两个表的视图,这两个表仅选择与DataDate表中的行匹配的行。如果你愿意,请索引它。读者现在将参考此视图,而不是表格。
  4. 批量插入行。 (您显然需要将DataDate添加到每一行。)
  5. 更新DataDate表。查看更新即时
  6. 随意删除昨天的行。
  7. SELECT表现不会受到影响;沿主键连接一行到150,000行应该对任何不到15年的服务器都没有问题。

    我经常使用这种技术,并且还在依赖sp_rename的过程中苦苦挣扎。修改架构的生产流程令人头疼。别。

答案 4 :(得分:0)

对于原始速度,我认为表中有大约150K行,我只是删除表,从头开始重新创建它(没有索引)然后重新加载。完成批量加载后,再创建索引。

这当然假设表格是空的/不存在的时间段是可接受的,听起来就像是这样。