我的分区表SELECT查询包括所有分区表,即使检查到位且constraint_exclusion = on。
插入触发器工作正常,新行插入到正确的表中。但是,无论我的WHERE子句如何,SELECT都会在所有表上运行。
这是我的配置:
constraint_exclusion = on (both in postgresql.conf and also tried with "ALTER DATABASE bigtable SET constraint_exclusion=on;")
主表:
CREATE TABLE bigtable (
id bigserial NOT NULL,
userid integer NOT NULL,
inserttime timestamp with time zone NOT NULL DEFAULT now()
)
儿童表1:
CREATE TABLE bigtable_2013_11 (CHECK ( inserttime >= DATE '2013-11-01' AND inserttime < DATE '2013-12-01' )) INHERITS (bigtable);
儿童表2:
CREATE TABLE bigtable_2013_12 (CHECK ( inserttime >= DATE '2013-12-01' AND inserttime < DATE '2014-01-01' )) INHERITS (bigtable);
存储过程:
CREATE OR REPLACE FUNCTION bigtable_insert_function()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.inserttime >= DATE '2013-11-01' AND NEW.inserttime < DATE '2013-11-01' ) THEN
INSERT INTO bigtable_2013_11 VALUES (NEW.*);
ELSEIF (NEW.inserttime >= DATE '2013-12-01' AND NEW.inserttime < DATE '2014-01-01' ) THEN
INSERT INTO bigtable_2013_12 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Bigtable insert date is out of range!';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
触发:
CREATE TRIGGER bigtable_insert_trigger BEFORE INSERT ON bigtable FOR EACH ROW EXECUTE PROCEDURE bigtable_insert_function();
这几乎是教科书的设置。插入工作正常:
INSERT INTO bigtable (userid, inserttime) VALUES ('1', now());
上面插入会导致新行正确插入'bigtable_2013_11'。
但是我无法让SELECT排除不相关的表。所有SELECT总是在所有表上运行。我希望在使用以下SELECT查询时排除bigtable_2013_12:
SELECT * FROM bigtable WHERE inserttime >= DATE '2013-11-01'::date AND inserttime < '2013-12-01'::date;
SELECT * FROM bigtable WHERE EXTRACT(MONTH FROM inserttime) = 11 AND EXTRACT (YEAR FROM inserttime) = 2013;
但结果总是这样:
"Result (cost=0.00..68.90 rows=17 width=20)"
" -> Append (cost=0.00..68.90 rows=17 width=20)"
" -> Seq Scan on bigtable (cost=0.00..0.00 rows=1 width=20)"
" Filter: ((inserttime >= '2013-11-02'::date) AND (inserttime < '2013-11-30'::date))"
" -> Seq Scan on bigtable_2013_11 bigtable (cost=0.00..34.45 rows=8 width=20)"
" Filter: ((inserttime >= '2013-11-02'::date) AND (inserttime < '2013-11-30'::date))"
" -> Seq Scan on bigtable_2013_12 bigtable (cost=0.00..34.45 rows=8 width=20)"
" Filter: ((inserttime >= '2013-11-02'::date) AND (inserttime < '2013-11-30'::date))"
为什么我的支票没有开始?我没有想法。一切似乎都正确设置。我错过了什么吗?任何帮助将不胜感激。
答案 0 :(得分:2)
这里有两件事。一个是seq扫描。另一个是union all(即追加运算符)。就我所知,后者完全是不可避免的。这就是表继承的工作原理 - 或者它最后一次使用它。 *但是*,这将我们带到前者,您可以在该日期字段上添加索引,以消除不必要的seq扫描并提前保释。
或者,可能与日期/时间戳转换相关。