我需要从PG数据库中删除大约200万行.我有一个我需要删除的ID列表.但是,我尝试这样做的任何方式都需要几天时间.
我尝试将它们放在一个表中,并在100个批次中进行.4天后,这仍然在运行,只删除了297268行.(我必须从ID表中选择100个id,删除该列表中的IN,从ids表中删除我选择的100个).
我试过了:
DELETE FROM tbl WHERE id IN (select * from ids)
Run Code Online (Sandbox Code Playgroud)
那也是永远的.很难判断多久,因为我看不到它的进展直到完成,但查询仍然在2天后运行.
当我知道要删除的特定ID时,只需要寻找从表中删除的最有效方法,并且有数百万个ID.
我无法理解锁与Postgres中的事务如何交互.
当我运行这个(长)查询时,我对发生的高度锁定感到惊讶:
BEGIN;
TRUNCATE foo;
\COPY foo FROM 'backup.txt';
COMMIT;
Run Code Online (Sandbox Code Playgroud)
该文件对于\COPY没有提到它需要什么级别的锁,但是这篇文章表明,它只能得到一个RowExclusiveLock.但是当我在以下期间运行此查询时\COPY:
SELECT mode, granted FROM pg_locks
WHERE relation='foo'::regclass::oid;
Run Code Online (Sandbox Code Playgroud)
我明白了:
mode granted
RowExclusiveLock true
ShareLock true
AccessExclusiveLock true
Run Code Online (Sandbox Code Playgroud)
AccessExclusiveLock来自哪里?我假设它来自TRUNCATE,这需要一个AccessExclusiveLock.但是TRUNCATE很快就完成了,所以我希望锁定能够快速释放.这给我留下了一些问题.
当事务中的命令获取锁时,是否在命令结束时(在事务结束之前)释放该锁?如果是这样,为什么我会观察到上述行为?如果没有,为什么不呢?实际上,由于事务直到事务才触及表COMMIT,为什么TRUNCATE事务中的事务需要阻塞表呢?
来自这篇文档http://www.postgresql.org/docs/current/static/explicit-locking.html
我知道PostgreSQL提供了各种锁模式来控制对表中数据的并发访问.
我的问题是我有很多会话将访问我的数据库,但我很困惑,我应该制作一个大的表与40列或许多表与较少的列(一对一的关系).
因为当我选择数据时,我将选择所有数据--->使用INNER JOIN从许多表中选择时需要更多时间,但从1个大表中选择需要的时间更少.所以如果我使用很多表格,我的php会响应得更慢.
但是当我只使用一个表时,许多会话将更新表中的数据,我害怕死锁或延迟,因为命令UPDATE,DELETE和INSERT在目标表上获取ROW EXCLUSIVE锁模式.通常,此锁定模式将由修改表中数据的任何命令获取.
任何人都可以建议我应该采用哪种方法?一张大桌子还是很多桌子?