Partitionin with check functions - Mailing list pgsql-admin
From | fatih ozturk |
---|---|
Subject | Partitionin with check functions |
Date | |
Msg-id | 20867.32524.qm@web111513.mail.gq1.yahoo.com Whole thread Raw |
Responses |
Re: Partitionin with check functions
|
List | pgsql-admin |
Hi My problem in partitioning is about using functions in table check constraints. let me explain it " DROP DATABASE partitioning; \set ON_ERROR_STOP y CREATE DATABASE partitioning; ALTER DATABASE partitioning set constraint_exclusion TO true; \c partitioning CREATE language plpgsql; CREATE TABLE mainlog (sel int); CREATE TABLE mainlog_p0 (CHECK (mod(sel,6)=0)) INHERITS (mainlog); CREATE TABLE mainlog_p1 (CHECK (mod(sel,6)=1)) INHERITS (mainlog); CREATE TABLE mainlog_p2 (CHECK (mod(sel,6)=2)) INHERITS (mainlog); CREATE TABLE mainlog_p3 (CHECK (mod(sel,6)=3)) INHERITS (mainlog); CREATE TABLE mainlog_p4 (CHECK (mod(sel,6)=4)) INHERITS (mainlog); CREATE TABLE mainlog_p5 (CHECK (mod(sel,6)=5)) INHERITS (mainlog); CREATE OR REPLACE FUNCTION trg_mainlog_partitioner() RETURNS TRIGGER AS $$ BEGIN IF mod(NEW.sel,6) = 0 THEN INSERT INTO mainlog_p0 VALUES (NEW.*); ELSIF mod(NEW.sel,6) = 1 THEN INSERT INTO mainlog_p1 VALUES (NEW.*); ELSIF mod(NEW.sel,6) = 2 THEN INSERT INTO mainlog_p2 VALUES (NEW.*); ELSIF mod(NEW.sel,6) = 3 THEN INSERT INTO mainlog_p3 VALUES (NEW.*); ELSIF mod(NEW.sel,6) = 4 THEN INSERT INTO mainlog_p4 VALUES (NEW.*); ELSIF mod(NEW.sel,6) = 5 THEN INSERT INTO mainlog_p5 VALUES (NEW.*); END IF; RETURN NULL; END; $$ language plpgsql; CREATE TRIGGER trg_mainlog_partitioner BEFORE INSERT ON mainlog FOR EACH ROW execute procedure trg_mainlog_partitioner(); INSERT INTO mainlog(sel) SELECT * FROM generate_series(1,1000); " partitioning=# SELECT * from only mainlog; sel ----- (0 rows) partitioning=# SELECT * from only mainlog_p1; sel ----- 1 7 13 19 25 31 ..... it seems tables contains expected datas. But lets explain queries partitioning=# explain SELECT * from mainlog where sel=123; QUERY PLAN ------------------------------------------------------------------------------ Result (cost=0.00..58.50 rows=18 width=4) -> Append (cost=0.00..58.50 rows=18 width=4) -> Seq Scan on mainlog (cost=0.00..40.00 rows=12 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p0 mainlog (cost=0.00..3.08 rows=1 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p1 mainlog (cost=0.00..3.09 rows=1 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p2 mainlog (cost=0.00..3.09 rows=1 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p3 mainlog (cost=0.00..3.09 rows=1 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p4 mainlog (cost=0.00..3.09 rows=1 width=4) Filter: (sel = 123) -> Seq Scan on mainlog_p5 mainlog (cost=0.00..3.08 rows=1 width=4) Filter: (sel = 123) (16 rows) i am expecting that query planer only scans "mainlog_p3" not the others since mod(123,6)=3 so 123 can only be in "mainlog_p3" table and scaning other tables is waste of time. What is the problem with my partitioning strategy? How can i make it fixed and make it working as i expected? Any suggestions Thanks for your interest Note: Forgive me, i can not give real table definitions. |
pgsql-admin by date: