3

我有一个结构简单的表格,如下所示:

tn( id integer NOT NULL primary key DEFAULT nextval('tn_sequence'),
                 create_dt TIMESTAMP NOT NULL DEFAULT NOW(),
                             ...............
                 deleted boolean );

create_dt是将行插入数据库时​​的时间戳。

deleted指示该行是否有用或不再有用。

我有以下查询:

select * from tn where create_dt > ( NOW() - interval '150 seconds ) and deleted = FALSE;
select * from tn where create_dt < ( NOW() - interval '150 seconds ) and deleted = FALSE;

我的问题是当行数增加时这些查询将如何减慢?例如,当行数超过 10K、20K 或 100K 时,是否会对速度产生很大影响?有什么办法可以优化这些查询吗?请注意,每 5 秒我会将超过 150 秒的行的“已删除”列变为“真”。

4

1 回答 1

4

表增长对性能的影响将取决于选择的查询计划、可用索引、查询的选择性以及许多其他因素。EXPLAIN ANALYZE关于查询可能会有所帮助。简而言之,如果您的查询只选择几行并且可以使用简单的 b-tree 索引,那么它通常不会减慢很多,只会随着索引的增长而减慢。另一方面,使用复杂的非索引条件或返回大量行的查询确实可能执行得非常糟糕。

您的问题似乎反映了问题我们应该如何处理一旦在 PostgreSQL 中过时就不会被查询的行?

那里给出的建议应该适用:

例如,您可能:

CREATE INDEX create_dt_when_not_deleted_idx 
ON tn (create_dt)
WHERE (NOT deleted);

这仅包括索引中deleted = 'f'(假设deleted为“非空”)的行。这与让他们完全从桌子上消失是不一样的。

  • 全表顺序扫描没有任何变化,deleted='t'仍然必须扫描行;和
  • 与不存在行相比,I/O 会更多deleted = 't',因为任何给定的堆页面都可能包含混合行deleted = 't'deleted = 'f'行。

CLUSTER您可以通过对包含 的索引进行 ing来减少后者的影响deleted。同样,这对顺序扫描没有影响。为了帮助进行顺序扫描,您必须在deleted.

Pg 9.2 的仅索引扫描应该(我认为,尚未测试)使用部分索引。当只能进行索引扫描时,部分索引应该与仅包含deleted = 'f'行的表上的索引一样快。

请注意,您需要控制表和索引膨胀。确保 autovaccum 运行非常频繁,并使用不需要手动管理的可用空间映射之类的当前版本的 PostgreSQL,并且具有最新的、表现最佳的 autovacuum。我推荐 9.0 或更高版本,最好是 9.1 或 9.2。调整 autovacuum 以积极运行。

在调整和测试性能时 - 使用 测试您的查询EXPLAIN ANALYZE,不要只是猜测。

于 2012-10-07T09:49:36.573 回答