我正在用C#编写一个应用程序,该应用程序将定期将数据从一个postgres表复制到另一个。我正在使用NPGSql库。
我遇到了以下问题:当有数千行要复制(>10k(时,程序运行非常缓慢。
我尝试过:
-
在我的第一次尝试中,我提取了整个目标表,然后将插入的数据与已经存在的数据进行比较。然后,我会写一个插入或更新语句,这取决于它是否已经存在但有更改,或者它是否根本不存在。这是最糟糕的解决方案,因为每个单独的语句都必须作为命令发送。
-
接下来,我试着把一个";关于冲突";触发器。这使我可以将所有插入作为批量插入INTO…发送。。。。语句,表将负责更新。这明显更快,但还不够快。
-
我读过Postgres的COPY方法,但它似乎不适合我的需求。看起来COPY只是一个插入,而不是追加销售。因为我多次修改这个表,所以有些数据是新的,但有些数据是需要更新的旧行。
如果我需要一个编辑行的选项,而不仅仅是对我的所有数据进行全面的大规模插入,有人能想出一种快速的UPSERT方法吗?
请让我知道我是否可以提供任何其他信息
非常感谢您抽出时间
首先,我假设表在不同的数据库上,否则我只会在DML中完成这一切。
我想副本肯定是你的朋友。没有更快的方法来提取或加载数据,然后可以让数据库来完成繁重的工作。
在源数据库上:
copy source_table
to '/var/tmp/foo.csv' csv;
在目的地数据库上:
truncate temp_table;
copy temp_table
from '/var/tmp/foo.csv' csv;
insert into destination_table
select *
from temp_table t
where not exists (
select null
from destination_table d
where t.id = d.id
);
update destination_table d
set
field1 = t.field1,
field2 = t.field2
from temp_table t
where
d.id = t.id and
(d.field1 is distinct from t.field1 or
d.field2 is distinct from t.field2)
如果数据随时可用,如果你能做这样的事情,那就太好了:
其他评论:
- 插入到使用了反联接,这是我最喜欢的插入缺失记录的构造
- 在更新过程中,重要的是要指定udped的标准——不要更新所有内容;只有那些已经改变的记录。这将对性能产生很大影响。希望有一定数量的字段可以用来确定记录是否已更改
如果有一个字段指示记录已经更新(last_update_date或类似的字段(,那么一个稍微懒惰和美妙的方法是删除这些记录,并让反联接插入重新插入它们。这将省略更新语句的需要,并且对于具有大量列的表来说,代码将少得多