根据手册中的这一页,indexes don't need to be maintained
. 但是,我们正在使用具有连续速率的 PostgresQL 表运行updates
,deletes
并且inserts
随着时间的推移(几天),查询性能会显着下降。如果我们删除并重新创建索引,查询性能就会恢复。
我们正在使用开箱即用的设置。
我们测试中的表目前一开始是空的,并且增长到 50 万行。它有一个相当大的行(很多文本字段)。
我们是searching based of an index, not the primary key
(我已经确认正在使用该索引,至少在正常情况下是这样)
该表被用作单个进程的持久存储。在带有 Java 客户端的 Windows 上使用 PostgreSQL。
我愿意放弃insert and update performance
以保持查询性能。
我们正在考虑重新架构应用程序,以便数据以允许我们定期删除和重建索引而不影响应用程序的方式分布在各种动态表中。但是,与往常一样,要使其正常工作需要时间,我怀疑我们在配置或使用中缺少一些基本的东西。
我们已经考虑了forcing vacuuming
and rebuild to run at certain times
,但我怀疑locking period for such an action would cause our query to block
. 这可能是一个选项,但有一些实时(3-5 秒的窗口)影响需要我们的代码进行其他更改。
附加信息: 表格和索引
CREATE TABLE icl_contacts
(
id bigint NOT NULL,
campaignfqname character varying(255) NOT NULL,
currentstate character(16) NOT NULL,
xmlscheduledtime character(23) NOT NULL,
...
25 or so other fields. Most of them fixed or varying character fiel
...
CONSTRAINT icl_contacts_pkey PRIMARY KEY (id)
)
WITH (OIDS=FALSE);
ALTER TABLE icl_contacts OWNER TO postgres;
CREATE INDEX icl_contacts_idx
ON icl_contacts
USING btree
(xmlscheduledtime, currentstate, campaignfqname);
分析:
Limit (cost=0.00..3792.10 rows=750 width=32) (actual time=48.922..59.601 rows=750 loops=1)
-> Index Scan using icl_contacts_idx on icl_contacts (cost=0.00..934580.47 rows=184841 width=32) (actual time=48.909..55.961 rows=750 loops=1)
Index Cond: ((xmlscheduledtime < '2010-05-20T13:00:00.000'::bpchar) AND (currentstate = 'SCHEDULED'::bpchar) AND ((campaignfqname)::text = '.main.ee45692a-6113-43cb-9257-7b6bf65f0c3e'::text))
而且,是的,我知道有各种各样的事情we could do to normalize and improve the design of this table
。其中一些选项可能对我们可用。
我在这个问题上的重点是理解how PostgresQL is managing the index and query over time (understand why, not just fix)
。如果要重新完成或进行重大重构,将会有很多变化。