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

时间:2013-12-05 20:52:27

标签: sql postgresql indexing clustered-index

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

1 个答案:

答案 0 :(得分:8)

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

表格的PostgreSQL聚类

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

  

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

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

E.g。如果你插入一个满足你的where子句的新行,它可能会被插入到表中的任何地方 - 例如其中存储了1990年的行。因此,这种假设并不成立:

  

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

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

群集索引

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

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

希望澄清它。