1

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

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(对于可用联系人)还是它们都会受到影响?

4

2 回答 2

3

与元组无关的部分索引不会得到更新。

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

于 2020-09-17T15:47:09.680 回答
2

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

于 2020-09-17T15:36:33.510 回答