使用部分索引更新和插入性能
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;
对于那些我创建了部分索引的查询:
- 对于 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;
- 对于 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 可以进行热更新(如果被更改的列不是索引的一部分,并且新元组在同一页上有空间),那么即使是相关索引也不需要获取已更新。
我有不同的查询从大型 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;
对于那些我创建了部分索引的查询:
- 对于 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;
- 对于 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 可以进行热更新(如果被更改的列不是索引的一部分,并且新元组在同一页上有空间),那么即使是相关索引也不需要获取已更新。