更新一个GIN索引可能会比较慢,这是因为倒排索引的天然特性造成的: 对一个堆行的插入 或更新可能导致对索引的很多次插入(每一次插入用于从被索引项中抽取的一个键)。 从 PostgreSQL 8.4 开始,GIN可以通过将新元组插入到一个临时的未排序的待处理条目列表中来 推迟很多这种工作。 当表被清理、自动分析、gin_clean_pending_list函数被调用 或者待处理 列表变得大于gin_pending_list_limit时, 这些条目被使用初始索引创建时使用的批量插入技术 移动到主GIN数据结构中。 这大幅度提高了GIN索引的更新速度,虽然带了一些额外的清理 负荷。 此外,这些开销可以通过用一个后台进程来取代一个前台进程执行。
这种方式的主要缺点是搜索必须在搜索普通索引之外扫描待处理条目的列表,并且因此一个
大型的待处理条目列表会显著地拖慢搜索。另一个缺点是,虽然大部分更新变快了,一次导致待处理列表变得“太大”的更新将导致一次立即清理循环并且因此会比其他更新慢很多。正确使用自动清理可以把这些问题的影响变得最小。
查询时,如果有未合并到索引中的PENDING LIST,那么会查询pending list,同时查询索引也的信息。
我们可以通过pageinspect插件来观察gin索引中pending list的内容.
例子:
bill=# create extension pageinspect ;
CREATE EXTENSION
bill=# show gin_pending_list_limit ;
gin_pending_list_limit
------------------------
4MB
(1 row)
建表:
bill=# create table t1(id int,arr int[]);
CREATE TABLE