Postgres忽略日期查询中的聚簇索引

abu*_*abu 3 sql postgresql indexing clustered-index

我有一个大表,我定期运行查询,如选择date_att> date'2001-01-01'.我试图通过在date_att上对表进行聚类来提高这些查询的速度,但是当我通过explain analyze运行这些查询时,它仍然选择按顺序扫描表,即使是在查询就像SELECT date_att那样简单,其中date_att> date '2001-01-01'.为什么会这样?我理解,由于查询返回表的大部分,优化器将忽略索引,但由于该表是由该属性聚类的,因此它不应该能够真正快速地通过表二进制搜索到日期点>'2001-01-01'并在此之后返回所有结果?此查询仍然需要与没有群集一样多的时间.

Mar*_*and 8

看起来你混淆了两个概念:

PostgreSQL集群表

根据PostgreSQL中的索引对表进行聚类,将表行(存储在堆表中)的顺序与聚类时索引中的顺序对齐.来自文档:

群集是一次性操作:随后更新表时,更改不会群集. http://www.postgresql.org/docs/9.3/static/sql-cluster.html

集群可能(通常)提高范围查询的查询速度,因为所选行通过巧合存储在堆表附近.没有什么可以保证这个订单!因此,优化器不能假设它是真的.

例如,如果插入一个满足where子句的新行,则可以将其插入表中的任何位置 - 例如,存储1990年的行.因此,这种假设并不成立:

但由于该表是由该属性聚类的,它不应该能够真正快速地二进制>在表中搜索到日期>'2001-01-01'并在此之后返回所有结果吗?

这将我们带到您提到的另一个概念:

聚集索引

这是完全不同的东西,PostgreSQL完全不支持,但许多其他数据库(SQL Server,带有InnoDB的MySQL以及称为'Index Organized Table'的Oracle)都不支持.

在这种情况下,表数据本身存储在索引结构中 - 没有单独的堆结构!因为它是一个索引,所以每个insert/ update/ 也保持订单delete.因此,您的假设将成立,实际上我希望上面提到的数据库的行为与您期望的一样(假设该date列是聚类键!).

希望澄清一下.