根据在手动,indexes don't need to be maintained。但是,我们与具有updatesdeletesinserts随着时间的推移(几天)的连续速度PostgreSQL表运行看到一个显著查询退化。如果我们删除并重新创建索引,查询性能被恢复。

我们正在使用开箱即用的设置。点击 在我们的测试表正在启动了空长到五十万行。 它有一个相当大的行(大量文本字段)。

我们是searching based of an index, not the primary key(I已确认该索引正在被使用,至少在正常条件下)

在表被用作用于单个处理的持久性存储。 在Windows上使用PostgreSQL与Java客户端。

我愿意放弃insert and update performance跟上查询性能。

我们正在考虑重新架构的应用程序,以便数据是跨各种动态表扩展的方式,使我们能够下降,并周期性重建索引,而不影响应用程序。然而,一如既往,有时间紧缩得到这个工作,我想我们失去了一些东西基本在我们的配置或使用。

我们已经考虑forcing vacuumingrebuild 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)。如果它做了或显著重构,将有很大的变化。

有帮助吗?

解决方案

自动真空应该做的伎俩,只要你将其配置为您所需的性能。

注意: 真空FULL:这将重建表统计和磁盘空间回收负荷。它锁定整个表。

真空度:这将重建表的统计信息并回收一些磁盘空间。它可以与生产系统并行运行,但产生大量的IO可以影响性能。

分析:这会重建查询规划的统计信息。这是通过真空触发,但可在其自己的运行。

更多详细注释发现这里

其他提示

至于性能,使用字符串,用于存储时间和状态信息是相当的瓶颈。首先,对文本索引效率极低,在同一天需要比较两个时间至少11对比(在你所使用的格式),但是使用时间键入它可以减少到一个简单的比较。这也影响了指数的大小,和一个大型的指数很难在搜索和数据库不会保留在内存中。同样的考虑也适用于状态栏。因此和指数的大小 - 如果它是一个很小的组状态,你应该整数映射到状态号使用,这将减少索引的节点。此外,该指数将是无用的,甚至使用theese内建类型,如果你不查询中指定的实际时间。

此闻起来像索引膨胀我。 I'l向您推荐此页

http://www.postgresql.org/docs/8.3/静态/例行reindex.html

,其表示在底部:

  

另外,对于B树索引一   新鲜构造指数是多少有些   更快地访问不是一个有   更新了很多次,因为   逻辑上相邻的页通常是   还在新物理上邻近的   建索引。 (这方面的考虑呢   目前不适用于非B树   索引。)这可能是值得的   周期性重建索引只是为了提高   访问速度。

这似乎与分页冲突你引用说,索引“不需要维护或调整。”

您是否尝试过“同时创建索引”?

是 '2010-05-20T13:00:00.000'?值xmlscheduledtime正在相比SQL的,一部分,或者作为一个参数提供

在规划如何运行查询,说一个字段必须小于与一个未知值提供的参数不给PostgreSQL的头绪。它不知道这是否会匹配几乎所有的行,或者几乎没有任何行。

阅读有关规划器用途的统计方法试图弄清楚为什么你的数据库使用它是巨大的计划时有所帮助。

您可以通过改变在复杂的索引字段的顺序,或创建新的索引获得更好的选择性能,与在有序(campaignfqname,currentstate,xmlscheduledtime)自那时以来该指数将带您直接到活动FQ名和目前的状态,你有兴趣,而索引扫描在xmlscheduledtime范围内都将是行你了。

这是一个教科书情况。你应该设置自动清理是很多更具侵略性。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top