使用CURRENT_TIMESTAMP查询时间戳分区表的效率

时间:2011-03-06 20:31:05

标签: sql postgresql timestamp partitioning

在PostgreSQL 9.0.3下给出以下表分区:

CREATE TABLE records (
  ts TIMESTAMP,
  ...
);

CREATE TABLE records_2010 (
  CHECK (ts >= '2010-01-01 00:00:00' AND ts < '2011-01-01 00:00:00')
) INHERITS (records);

CREATE TABLE records_2011 (
  CHECK (ts >= '2011-01-01 00:00:00' AND ts < '2012-01-01 00:00:00')
) INHERITS (records);

我希望以下SELECT查询具有相同的EXPLAINed计划,仅查询“records”和“records_2011”,但它们有所不同:

BEGIN;
-- Assume CURRENT_TIMESTAMP is 9 a.m. on 5 March 2011
SELECT * FROM records WHERE ts >= '2011-03-05 09:00:00'; -- scans 2 tables
SELECT * FROM records WHERE ts >= CURRENT_TIMESTAMP;     -- scans all 3 tables
COMMIT;

鉴于CURRENT_TIMESTAMP在其封闭事务的持续时间内返回一个常量值,为什么使用CURRENT_TIMESTAMP的查询不利用Postgres的分区并且只扫描两个表?

更新

目前这是不可能的,但它被认为是一个需要改进的领域。 PostgreSQL 9.1可以address this behavior in the query executor

1 个答案:

答案 0 :(得分:5)

如果您是第一次运行查询,PostgreSQL会确定一个查询计划。这是一项昂贵的操作,结果是缓存的。所以查询也必须适用于将来的执行。

无论何时运行,您的第一个查询都不会需要records_2010

但第二个查询使用变量CURRENT_TIMESTAMP。优化器不知道时间只能增加,并生成一个适用于任何ts值的计划。这意味着它必须查看所有三个表。