我们正在研究Heroku上的Postgres数据库。我们需要使用正则表达式替换多个字符串来更新大约500万行,这意味着可能总共执行大约1亿次更新。
我们正在以这种方式更新它:(使用psycopg2)
for element in list:
cursor.execute("Update table set text = regexp_replace(text, %s, 'NewWord', 'gi') where date >= '2017-12-31';", [element])
数据库是实时的并且链接到我们的Django网站,我们需要在3天内推出一项新功能,要求对数据库进行此更新。 Postgres指南说,如果我们删除索引它会快得多,但删除外键索引可能会阻止我们的一些django功能并将网站关闭。即便如此,我们也可以在周末期间将这一方面减少一到两天,但仅此而已。
所以:
答案 0 :(得分:0)
您的查询(为简单起见,我删除了参数化,并将{table,date,text}替换为{ztable,zdate,ztext},因为它是关键字):
Update ztable
set ztext = regexp_replace(ztext, 'Oldword', 'NewWord', 'gi')
where zdate >= '2017-12-31';
可以通过在where子句中添加额外条件来加速,例如:
Update ztable
set ztext = regexp_replace(ztext, 'Oldword', 'NewWord', 'gi')
where zdate >= '2017-12-31'
AND ztext LIKE '%Oldword%'
;
如果更新实际上对行没有任何作用,这将避免创建额外的行版本。 (如果实际更改了行,则更新需要1个读取I / O +大约3个I / O,受影响的磁盘块数取决于sparsety和行大小)
额外注意:如果ztext
列上有索引:扔掉它;它可能没用。
通过删除前端的循环并将所有逻辑放在UPDATE中,可以获得额外的性能。