she*_*Roy 4 postgresql cursor sql-delete
我是 Postgres 新手,有一项任务是从未分区创建的活动表中删除记录。现在我的想法是创建一个游标来以受控的方式删除记录。
我脑子里的步骤:
这有意义吗?
Erw*_*ter 11
只是DELETE。忘记光标。
除非您的表很大并且要删除很大比例的行,否则批量执行此操作是没有意义的。即便如此,也几乎没有任何意义。我能想到的唯一原因是允许VACUUM提前删除死元组,这在特殊情况下可能会有所帮助。或者避免锁定争用(可能的死锁?),但这引出了一个问题:为什么要删除的行首先应该由并发事务锁定。
为此,每行都有锁。并发INSERT或UPDATE不同行不存在冲突。(如果您有针对某些相同行的更新,则会遇到更大的问题。)并且编写器不会阻止读取器在 Postgres 上阻止读者。
您可以使用该选项创建SQL 游标WITH HOLD,然后在单独的事务中使用它DELETE ... WHERE CURRENT OF。但无论如何,您都必须投入FOR UPDATE,锁定所有受影响的行。很少有意义,除非您想快速锁定所有受影响的行,但在删除之前仍对它们执行某些操作,并且可能有更聪明的方法......
在单独的事务中对大数据进行分区是有意义的UPDATE,以便可以在热更新中重用死元组(在手动更新之后VACUUM或autovacuum已启动)。但这几乎不适用于DELETE不重复使用空间的操作。而且,DELETE速度比 快很多UPDATE。
万一您仍然需要批量执行此操作,仍然不要使用游标。使用类似的东西:
\nWITH cte AS (\n SELECT id -- your PK\n FROM tbl\n WHERE date < $something -- your condition\n -- ORDER BY ??? -- optional, see below\n LIMIT 50000\n FOR UPDATE -- SKIP LOCKED ?\n )\nDELETE FROM tbl\nUSING cte\nWHERE tbl.id = cte.id;\nRun Code Online (Sandbox Code Playgroud)\n重复直到找不到行。
\n如果您的数据(大部分)以某种方式进行物理排序,则可以相应地对行进行排序(引用的ORDER BY)。这ORDER BY会带来自己的成本,但每个都DELETE可能能够访问更少的具有聚集行的数据页,并且这样速度更快。取决于用例;如果ORDER BY能用指数的话,前景会更好。
看:
\n\n| 归档时间: |
|
| 查看次数: |
19268 次 |
| 最近记录: |