在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。
答案 0 :(得分:5)
如果您是第一次运行查询,PostgreSQL会确定一个查询计划。这是一项昂贵的操作,结果是缓存的。所以查询也必须适用于将来的执行。
无论何时运行,您的第一个查询都不会需要records_2010
。
但第二个查询使用变量CURRENT_TIMESTAMP
。优化器不知道时间只能增加,并生成一个适用于任何ts
值的计划。这意味着它必须查看所有三个表。