使用部分索引更新和插入性能

Update and insert performance with partial indexes

我有不同的查询从大型 table(大约 100-200M 行)中获取数据。我已经为我的 table 创建了部分索引,使用不同的谓词来适应查询,因为我知道每个查询。 例如,table 类似这样:

CREATE TABLE public.contacts (
    id int8 NOT NULL DEFAULT ssng_generate_id(8::bigint),
    created timestamp NOT NULL DEFAULT timezone('UTC'::text, now()),
    contact_pool_id int8 NOT NULL,
    project_id int8 NOT NULL,
    state_id int4 NOT NULL DEFAULT 10,
    order_x int4 NOT NULL,
    next_attempt_date timestamp NULL,
    CONSTRAINT contacts_pkey PRIMARY KEY (id)
);

并且有两种类型的查询:

SELECT * FROM contacts WHERE contact_pool_id = X AND state_id = 10 ORDER BY order_x LIMIT 1;

SELECT * FROM contacts WHERE contact_pool_id = X AND state_id = 20 AND next_attemp_date <= NOW ORDER BY next_attemp_date LIMIT 1;

对于那些我创建了部分索引的查询:

  1. 对于 state_id = 10(新联系人)

CREATE INDEX ix_contacts_cpid_orderx_id_for_new ON contacts USING btree (contact_pool_id, order_x, id) WHERE state_id = 10;
  1. 对于 state_id = 20(可用联系人)
CREATE INDEX ix_contacts_cpid_nextattepmdate_id_for_available ON contacts USING btree (contact_pool_id, next_attempt_date, id) WHERE state_id = 20;

对我来说,那些部分索引比单个索引更快。

更新和插入性能如何?如果我更改 state_id = 20 的行,它会仅影响索引 2(对于可用联系人)还是它们都会受到影响?

是的,使用部分索引,您只需为满足 WHERE 条件的行支付修改索引的开销,因此您永远只需要同时修改最多一个索引(除非您将 state_id 从 10 更改为 20,反之亦然)。

与元组不相关的部分索引将不会更新。

如果 PostgreSQL 可以进行热更新(如果被更改的列不是索引的一部分,并且新元组在同一页上有空间),那么即使是相关索引也不需要获取已更新。