经过大量的谷歌搜索,我想我会问这个问题。我有一段代码对postgres(9.2)数据库执行以下操作:
我对postgres的阅读告诉我,我应该能够做到这一点,并且仍然允许其他用户从表中进行选择(实际上甚至使用现有的索引,因为它们尚未被删除),而此操作正在进行中。 / p>
我实际发现的是桌面上的所有其他查询(它们是所有选择查询)都被卡住了。在查看pg_locks和pg_stat_activity表后,我发现我的事务已在表上创建了一个AccessExclusiveLock,阻止其他查询运行。一旦此事务完成,所有其他查询都可以正常执行。
所以,我的问题是 - 为什么创建索引/插入数据会在表上创建独占锁?不应该使用较少侵入性的锁(例如SHARE锁)吗?
我的基础是我阅读官方文档here - 所以我不会被任何人要求RTFM:)
谢谢,
Jalpesh
答案 0 :(得分:3)
我也想要这个,但你不能这样做。
它不是创建索引,也不是在表上采用AccessExclusive锁的插入,它是正在执行此操作的drop index。
该文档没有提供获取每种类型锁的每种情况的详尽列表 - 它仅提供说明性示例(但也许这个示例应包含在其中)。
我相信代码的很多部分都假设索引不会在表上的AccessShare锁定时消失。因此,删除索引需要与之冲突。
答案 1 :(得分:1)
我想您希望能够在批量插入期间查询您的表,并通过在插入期间不维护索引来加速此批量插入。
我认为您可以使用此程序实现此目的:
begin;
maxid = select max(id) from table_name;
create index table_name_id_tmp_idx where id<=maxid;
drop index table_name_id_idx;
commit;
begin;
do_bulk_insert();
create index table_name_id_idx on table_name(id);
drop index table_name_id_tmp_idx;
commit;
对于每个索引都不可能,因为您需要此where
谓词用于部分索引,该索引将为现有行返回true
并为{}返回false
。但是串行列,时间戳等可以工作。