CLUSTER对性能的影响


8

我正在尝试优化我的Postgres 9.2数据库以加快具有日期限制的查询。

我有一timestamp列,但大多数情况下我都想找一天,所以我创建了一个timestampdate解析的索引:

CREATE INDEX foo_my_timestamp_idx
ON foo
USING btree
((my_timestamp::date) DESC);

现在,为了提高性能,我CLUSTER foo使用上面的索引表:

CLUSTER foo USING foo_my_timestamp_idx;

根据SQL-CLUSTER上的手册,该表

根据索引信息进行物理重新排序

我想知道使用表PK(请说id_foo)对其他查询的性能是否有影响。有没有缺点?

Answers:


10

是的,可能会有弊端。如果另一个查询查看的日期不是由日期确定的另一个数据段,则如果现在将行分布在更多数据页上,则可能会降低性能。就像您的第一个查询获利一样。那完全取决于您的问题以外的信息。

使用表PK的其他查询(比如说id_foo)

那可能是什么。这取决于你拥有什么,你询问什么确切。查询单行不会受到任何影响,但可能会影响多行。

请注意,CLUSTER像在原始状态下一样重写表VACUUM FULL(删除死元组,压缩表的物理大小,重写索引),因此您可能会看到对读取性能的直接正面影响,而与排序顺序无关。(很像VACUUM FULL。)
之后CLUSTER,您可能还想VACUUM在表上运行一个普通表以更新可见性图 -这可能允许仅索引扫描。

CLUSTER随写入频率而缩小的所有好处。

另外,如果表有很多更新,CLUSTER则实际上可以通过删除同一数据页上HOT更新的“摆动空间”来损害写入性能。您可以使用FILLFACTOR低于100 的设置来抵消这种影响。同样,这取决于更新的行的位置等。

有关:

无论哪种方式,我都不会在上建立索引和群集my_timestamp::date,而是my_timestamp直接在上建立索引和群集。一无所有,收获了一些。演员表很便宜,但根本不便宜。并且索引可以支持更多查询。

CREATE INDEX foo_my_timestamp_idx ON foo (my_timestamp);

即使一个date磁盘仅占用4个字节,而timestamp占用8个字节,对于您的情况而言,差异通常会丢失到对齐填充中,并且两个索引的大小完全相同

表达式索引在同一天产生的多行顺序是任意的。仍然会有两个相同的时间戳,但是通常很少有6个小数位。除此之外,您还可以获得行的确定性顺序,这可以具有多种优势。

我也删除了DESC关键字,因为Postgres几乎可以像向前一样快速地向后读取索引。(不过,排序顺序对于多列索引很重要!)更多:

代替:

SELECT * FROM foo
WHERE my_timestamp::date = '2016-07-25';

您现在将使用:

SELECT * FROM foo
WHERE  my_timestamp >= '2016-07-25'  -- this is a timestamp literal now
WHERE  my_timestamp <  '2016-07-26';

相同的性能。

如果您不需要列的时间分量可言,转换列date...

如何回滚CLUSTER

CLUSTERROLLBACK只要未提交事务,就可以像使用任何其他常规命令一样回滚单个表上的表。

但是,我引用了手册

CLUSTER不带任何参数的参数将重新组合调用用户所拥有的当前数据库中所有先前群集的表,或者重新组合所有此类表(如果由超级用户调用)。这种形式的CLUSTER不能在事务块内执行。

您始终可以CLUSTER使用其他索引运行,以再次更改行的物理顺序。


令人毛骨悚然的答案,那么我需要问如何“回滚” CLUSTER?我现在需要CLUSTER使用PK吗?
ilovkatie

@ilovkatie:我添加了一些如何回滚。
Erwin Brandstetter,2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.