我发现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索引的不同普通表上运行查询时,两个查询都使用该索引。
我们应该在分区表索引上做什么特别的事情?
发布于 2016-04-06 22:45:36
我假设你知道"partitions“是Postgres中的表。在检索表的大部分部分(大于~5%,这取决于许多细节)时,索引通常是而不是,因为在这种情况下,只按顺序扫描表通常会更快。
此外,在第一个查询中,您似乎从涉及的分区中选择了所有行。索引没有用处...
通常,带有=的等式谓词比带有>=.Think的谓词更具选择性的:
您的第一个date >= '2015-07-01'查询从分区中检索所有行(猜测,我需要看到确切的定义)。使用索引只会增加管理成本。但是您的第二个date = '2015-07-01'查询只获取了一个很小百分比的。Postgres预计索引扫描会更快。
发布于 2016-04-06 22:58:41
也许那样会更快些?运行您的查询,然后执行以下操作:
SET enable_seqscan=false再运行一次。
https://stackoverflow.com/questions/36446299
复制相似问题