我有一个脚本在我的数据库中的每个项目上运行一个函数来提取学术引用。数据库很大,所以脚本需要大约一周的时间才能运行。如何处理巨大的结果集而不丢失任何项目
在此期间,项目被添加并从数据库中删除。
数据库太大而无法完全进入内存,所以我必须通过它来处理所有项目。
有没有办法确保当脚本结束时,所有的项目都被处理了?这是一个简单的解决方案吗?到目前为止,我的研究还没有显示出任
PS:锁定表一周不是一个选项!
我有一个脚本在我的数据库中的每个项目上运行一个函数来提取学术引用。数据库很大,所以脚本需要大约一周的时间才能运行。如何处理巨大的结果集而不丢失任何项目
在此期间,项目被添加并从数据库中删除。
数据库太大而无法完全进入内存,所以我必须通过它来处理所有项目。
有没有办法确保当脚本结束时,所有的项目都被处理了?这是一个简单的解决方案吗?到目前为止,我的研究还没有显示出任
PS:锁定表一周不是一个选项!
我会将时间戳列“modified_at”添加到默认为null的表中。所以任何新的项目都可以被识别。
然后,您的脚本可以根据该列选择要处理的块。
update items
set modified_at = current_timestamp
from (
select id
from items
where modified_at is null
limit 1000 --<<< this defines the size of each "chunk" that you work on
) t
where t.id = items.id
returning items.*;
这将更新1000行没有被处理为正在处理的行,并将在单个语句中返回这些行。然后,您的工作可以在返回的项目上工作。
新行需要添加modified_at = null
,并且您的脚本将在您下次运行时根据where modified_at is null
条件接收它们。
如果您还在处理它们时更改项目,则需要相应地更新modified_at
。在您的脚本中,您将需要在某处存储最后一次处理的开始。使用
where modified_at is null
or modified_at < (last script start time)
处理脚本的下一次运行,然后可以选择项目,如果你只处理每个项目只有一次(然后再也没有),你并不真的需要一个时间戳,一个简单的布尔(如is_processed
)也可以。
听起来像一个非常坚实的计划。意味着数据库中有一个额外的列,但看起来没有办法解决这个问题。 – mlissner
你有多久需要运行这个脚本? –
每隔几个月一次,给予或服用? – mlissner