即使更新的列不是索引列,postgresql 也会更新索引吗?

Does postgresql update index even when the updated columns aren't the indexed ones?

我想用 GINGiST 索引数组列。然而,GIN 在 insert/update 操作中速度较慢这一事实让我想知道它是否会对性能产生任何影响——即使索引列本身将保持静态。 因此,假设,例如,我有一个 table 列 (A, B, C) 并且 B 被索引,如果我只更新列 C?

,索引会更新吗

视情况而定:^)

通常情况下,PostgreSQL 将不得不修改索引,即使索引列中没有任何变化,因为 PostgreSQL 中的 UPDATE 创建了一个新的行版本,因此您需要一个新的索引条目来指向table.

中行的新位置

由于这是不幸的,所以有一种称为“热更新”的优化:如果 none 的索引列被修改 则有在包含原始行 的块中有足够的空闲 space,PostgreSQL 可以创建一个未从外部引用的“heap-only 元组”,因此不需要新的索引条目。

您可以降低 table 上的 fillfactor 以增加热更新的可能性。

有关详细信息,您可能需要阅读 my article on the topic

Laurenz Albe 的回答很棒。以下部分是我的解读。
因为ginarray_ops不能做index only scan。也就是说即使只查询数组列,也只能使用位图索引扫描。用于位图扫描。低填充因子,您可能不需要访问提取页面。

演示:

begin;
create table test_gin_update(cola int, colb int[]);
insert into  test_gin_update values (1,array[1,2]);
insert into  test_gin_update values (1,array[1,2,3]);
insert into  test_gin_update(cola, colb) select g, array[g, g + 1] from generate_series(10, 10000) g;
commit;

例如,select colb from test_gin_update where colb = array[1,2];请参阅以下查询计划。 因为 GIN 无法区分 array[1,2]array[1,2,3] 那么即使我们创建了 gin 索引。 create index on test_gin_update using gin(colb array_ops );我们只能使用位图索引扫描。

                                 QUERY PLAN
-----------------------------------------------------------------------------
 Bitmap Heap Scan on test_gin_update (actual rows=1 loops=1)
   Recheck Cond: (colb = '{1,2}'::integer[])
   Rows Removed by Index Recheck: 1
   Heap Blocks: exact=1
   ->  Bitmap Index Scan on test_gin_update_colb_idx (actual rows=2 loops=1)
         Index Cond: (colb = '{1,2}'::integer[])
(6 rows)