PG并发/在线创建索引


PG从较早的版本就支持在线并发创建索引(不长时间阻塞DML),这对于如今停机时间越来越少的OLTP系统来说是非常重要的特性之一:

1、先不使用concurrently参数创建索引,此时insert操作会阻塞,但是创建索引所消耗的时间较短:

表数据量约为5百万

test=# \timing on
Timing is on.
test=#

test=# create index relname_i on pgclass(relname);
CREATE INDEX
Time: 17189.968 ms

可见消耗时间为17秒

2、使用concurrently参数,并发创建索引:

test=# create index concurrently relname_i2 on pgclass(relname) ;
CREATE INDEX
Time: 27732.662 ms

可见所消耗的时间约为28秒,相比非concurrently方式来说,时间明显变长,但是在创建索引的过程中,另开一个窗口来执行的insert操作等均是无阻塞的:

test=# insert into pgclass select * from pg_class;
INSERT 0 301
test=# insert into pgclass select * from pg_class;
INSERT 0 301
test=# insert into pgclass select * from pg_class;
INSERT 0 301
test=# insert into pgclass select * from pg_class;
INSERT 0 301
test=# insert into pgclass select * from pg_class;
INSERT 0 301

两种方法创建的索引大小并无区别:

test=# select pg_size_pretty(pg_relation_size(‘pgclass’));

pg_size_pretty

922 MB
(1 row)

Time: 6.156 ms
test=# select pg_size_pretty(pg_relation_size(‘relname_i’));

pg_size_pretty

185 MB
(1 row)

Time: 0.444 ms
test=# select pg_size_pretty(pg_relation_size(‘relname_i2’));

pg_size_pretty

185 MB
(1 row)