首先请允许我说我在SQL Server 2005上运行,因此我无法访问MERGE
。
我有一个约150k行的表,我每天都会从文本文件中更新。当行从文本文件中删除时,我需要从数据库中删除它们,如果它们发生变化或者是新的,我需要相应地更新/插入。
经过一些测试后,我发现性能明智的是,执行完全删除然后从文本文件批量插入而不是通过执行更新/插入的行逐行读取是指数级更快。但是,我最近发现了一些帖子,讨论使用临时表和MERGE
语句的输出来模仿SQL Server 2008的UPDATE
功能。
我对此感兴趣,因为我正在调查当表没有行时如何消除删除/批量插入方法中的时间。我仍然认为这种方法最快,所以我正在寻找解决空表问题的最佳方法。
由于
答案 0 :(得分:5)
我认为你最快的方法是:
答案 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)
有一种方法可以在零停机时间内更新表:在表中保留两天的数据,并在加载新行后删除旧行!
SELECT
表现不会受到影响;沿主键连接一行到150,000行应该对任何不到15年的服务器都没有问题。
我经常使用这种技术,并且还在依赖sp_rename
的过程中苦苦挣扎。修改架构的生产流程令人头疼。别。
答案 4 :(得分:0)
对于原始速度,我认为表中有大约150K行,我只是删除表,从头开始重新创建它(没有索引)然后重新加载。完成批量加载后,再创建索引。
这当然假设表格是空的/不存在的时间段是可接受的,听起来就像是这样。