使用动态参数检查约束

时间:2015-11-05 09:30:34

标签: sql postgresql

我正在使用PostgreSQL创建分区表。

CREATE TABLE tt_parent
(
    id integer,
    log_time timestamp with time zone,
    server_id integer,
    name text,
    CONSTRAINT tt_parent_pkey PRIMARY KEY (id)
)

CREATE TABLE tt_1_2015_week42 (
 CHECK ( server_id = 1 AND log_time >= (to_timestamp('2015-42', 'IYYY-IW')) AND log_time <= (to_timestamp('2015-42', 'IYYY-IW') + '6 days'::interval)
) INHERITS (tt_parent);

CREATE TABLE tt_1_2015_week43 (
 CHECK ( server_id = 1 AND log_time >= (to_timestamp('2015-43', 'IYYY-IW')) AND log_time <= (to_timestamp('2015-43', 'IYYY-IW') + '6 days'::interval)
) INHERITS (tt_parent);

CREATE TABLE tt_1_2015_week44 (
 CHECK ( server_id = 1 AND log_time >= (to_timestamp('2015-44', 'IYYY-IW')) AND log_time <= (to_timestamp('2015-44', 'IYYY-IW') + '6 days'::interval)
) INHERITS (tt_parent);

当我在查询下面触发时创建上面的子表后,它会扫描所有子表。

EXPLAIN SELECT * FROM tt_parent 
WHERE server_id = 1 
AND (log_time >= '2015-10-12 00:00:00'::TIMESTAMP WITH TIME ZONE) 
AND (log_time <= '2015-10-15 00:00:00'::TIMESTAMP WITH TIME ZONE);

从上面的查询中,where子句中的log_time是第42周。所以查询应该只扫描&#34; tt_1_2015_week42&#34;儿童表。 为什么上面的查询会扫描所有3个子表?

使用动态值检查约束不起作用?我们不能使用&#34; to_timestamp&#34;函数内部检查约束? 如何修改上面的子表检查约束,以便查询只能扫描第42周表。

1 个答案:

答案 0 :(得分:0)

1)您的检查条件是两个相邻分区之间缺少的时间段。例如,差距:

from: to_timestamp('2015-42', 'IYYY-IW') + '6 days'::interval --2015-10-18 00:00:00
to:   to_timestamp('2015-43', 'IYYY-IW'))                     --2015-10-19 00:00:00

我会写:

CHECK (
    server_id = 1 AND
    log_time >= '2015-10-12'::timestamptz AND
    log_time < '2015-10-12'::timestamptz + interval '1 week' --'<' sign, not '<=' to avoid overlapping
)

2)要获得您想要的内容,您需要将constraint_exclusion选项设置为partition(这应该是默认值)。