Postgres未在分区表中使用索引进行范围查询



我发现Postgres没有在分区表上使用范围查询的索引。

父表及其分区的日期列使用btree进行索引。

像这样的查询:

select * from parent_table where date >= '2015-07-01';

不使用索引。

EXPLAIN结果:

Append  (cost=0.00..106557.52 rows=3263963 width=128)
->  Seq Scan on parent_table  (cost=0.00..0.00 rows=1 width=640)
    Filter: (date >= '2015-07-01'::date)
->  Seq Scan on z_partition_2015_07  (cost=0.00..106546.02 rows=3263922 width=128)
    Filter: (date >= '2015-07-01'::date)
->  Seq Scan on z_partition_2015_08  (cost=0.00..11.50 rows=40 width=640)
    Filter: (date >= '2015-07-01'::date)

但像这样的查询:

select * from parent_table where date = '2015-07-01'

使用索引。

EXPLAIN结果:

    Append  (cost=0.00..30400.95 rows=107602 width=128)
->  Seq Scan on parent_table  (cost=0.00..0.00 rows=1 width=640)
    Filter: (date = '2015-07-01'::date)
->  Index Scan using z_partition_2015_07_date on z_partition_2015_07  (cost=0.43..30400.95 rows=107601 width=128)
    Index Cond: (date = '2015-07-01'::date)

当我在具有索引date的另一个普通表上运行查询时,两个查询都使用索引。

我们应该对分区表索引做什么特别的事情?

我想您已经知道"分区"在Postgres中是独立的表。索引通常在检索表的大部分时使用而不是(超过约5%,这取决于许多细节),因为在这种情况下,只按顺序扫描表通常会更快。

更重要的是,您似乎在第一个查询中从涉及的分区中选择了所有行。不用于索引。。。

一般来说,具有=的相等谓词比具有>=的谓词更有选择性

使用date >= '2015-07-01'的第一个查询从分区中检索所有行(猜测,我需要查看确切的定义)。使用索引只会增加管理成本。但是使用date = '2015-07-01'的第二个查询只获取小百分比。Postgres预计索引扫描会更快。

也许那样会更快?运行您的查询,然后执行以下操作:

SET enable_seqscan=false

然后再运行一次。

最新更新