用数百万条记录更新表上的记录

时间:2014-01-03 13:08:12

标签: python sql django postgresql

我们有9列的表,并且pk被索引。我们有169.3百万条记录,最高可达250M。每次收到更新时,我都必须从数据库中获取大约40,000行,以便使用另一个索引列名称fk进行比较。我处理完毕后:

pk_update_nc = [pk1, pk2, pk5, .....pk40000]
pk_update_PN = [pk3, pk4, pk6, .....pk35090]
new_rows = [[row1], [row2], [row3], [row40000]]

以上数据只是建议:

  

更新表并设置列状态='NC',其类型不同   character(3)其中pk在pk_update_nc更新表和set列   status ='PN',其类型是变化的字符(3),其中pk in   pk_update_PN

     

从new_rows

向表中插入行

更新和插入的最佳方式是什么?

方法一:

start_transaction:
for pk in pk_update_nc:
    update table set status='NC' where table.pk = pk
for pk in pk_update_PN:
    update table set status='PN' where table.pk = pk
for row in new_rows:
    insert into table row = row
commit

方法2:

start_transaction;
update table set status='NC' where table.pk in pk_update_nc;
update table set status='PN' where table.pk in pk_update_PN;
insert into table values rows
commit

方法3:

fill list of updated records list with rows instead of complete records,
insert all records to table
start_transaction:
delete from table where fk = fk_provided;
insert all rows, updated + new using \copy or django bulk create
commit;
  
      
  • 第三种方法请求的解释。*这意味着从数据库和本地进程获取行,这在每种方法中都是正常的   而不是更新数据库,我们改变旧记录认为它们是新的。   从具有索引列的fk的数据库中删除所有记录,   然后使用\ copy将所有记录作为新记录插入。 \ copy insert records   神奇地快。 for \ copy visit postgresql COPY-TO/COPY-FROM
  •   

方法4? 推荐

常见问题:

  

为什么我要从db中提取40,000行?

     

这是因为我们必须根据新记录处理这些记录   旧记录和新记录的表单状态,旧行从许多用途传递   案件最终确定其状态。这样就可以得出每行的多次点击   并影响性能。这就是我决定提取数据的原因   最终更新前在本地处理。现在我们希望尽可能少的命中   性能更新数据库。

     

并发问题:

     

我们通过锁定要处理的表来解决此问题。和下一张表   锁定相同的记录,直到上一个任务为止   完成。这限制了用户处理相同的fk表   同时处理。关于数据库的问题可能是,我应该   更新和处理时锁定数据库,可能需要1-2   分钟?可以锁定数据库以仅更新,这需要更少   时间。

     

工具:

  • psql postgresql 9.1 python 2.7 django 1.5

1 个答案:

答案 0 :(得分:1)

你正试图将口红涂在猪身上。

检索40k行,在某些客户端应用程序中操作它们并将其写回来非常效率低下。最重要的是,您很容易在多用户环境中遇到并发问题。如果您在使用应用中的数据时数据库中的某些内容发生了变化,该怎么办?如何解决这些冲突?

执行此操作的正确方法(如果可能的话)是使用基于集合的操作在数据库中执行此操作。

Data-modifying CTEs对于处理多个表中的数据的更复杂操作特别有用。 This search here on SO提出了几个例子。