是的,可能会有弊端。如果另一个查询查看的日期不是由日期确定的另一个数据段,则如果现在将行分布在更多数据页上,则可能会降低性能。就像您的第一个查询获利一样。那完全取决于您的问题以外的信息。
使用表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
?
CLUSTER
ROLLBACK
只要未提交事务,就可以像使用任何其他常规命令一样回滚单个表上的表。
但是,我引用了手册:
CLUSTER
不带任何参数的参数将重新组合调用用户所拥有的当前数据库中所有先前群集的表,或者重新组合所有此类表(如果由超级用户调用)。这种形式的CLUSTER
不能在事务块内执行。
您始终可以CLUSTER
使用其他索引运行,以再次更改行的物理顺序。
CLUSTER
?我现在需要CLUSTER
使用PK吗?