2010-02-25 5 views
3

expiredtype_id 두 개의 열로 분할 된 테이블이 있습니다. expired은 부울이며 범위에 따라 type_id 파티션입니다. 표 예 :이상하게 작동하는 PostgreSQL 파티션 제약

mos_active_1 
... 
mos_active_15 
mos_expired_1 
... 
mos_expired_15 

이 내 제약이처럼 설정은 :

ADD CONSTRAINT mos_active_1_check CHECK (expired = false AND type_id < 100) 
... 
ADD CONSTRAINT mos_expired_1_check CHECK (expired = true AND type_id < 100) 

지금은 예상처럼 SELECT * from mos WHERE expired = true AND type_id = 34 모든 것이, 단지 mos_expired_1 치면 작품 실행합니다.

Result (cost=0.00..19.77 rows=2 width=627) 
    -> Append (cost=0.00..19.77 rows=2 width=627) 
     -> Seq Scan on mos (cost=0.00..11.50 rows=1 width=627) 
       Filter: (expired AND (type_id = 34)) 
     -> Index Scan using index_mos_expired_1_on_type_id_and_region_id on mos_expired_1 mos (cost=0.00..8.27 rows=1 width=627) 
       Index Cond: (type_id = 34) 
       Filter: expired 

는 Strangly 한 정도로 SELECT * from mos WHERE expired = false AND type_id = 34하지 작업을 수행합니다. EXPLAINmos_expired_1mos_active_1이 쿼리됨을 나타냅니다.

Result (cost=0.00..2464.71 rows=5863 width=150) 
    -> Append (cost=0.00..2464.71 rows=5863 width=150) 
     -> Seq Scan on mos (cost=0.00..11.50 rows=1 width=627) 
       Filter: ((NOT expired) AND (type_id = 34)) 
     -> Index Scan using index_mos_expired_1_on_type_id_and_region_id on mos_expired_1 mos (cost=0.00..8.27 rows=1 width=627) 
       Index Cond: (type_id = 34) 
       Filter: (NOT expired) 
     -> Bitmap Heap Scan on mos_active_1 mos (cost=113.68..2444.95 rows=5861 width=150) 
       Recheck Cond: (type_id = 34) 
       Filter: (NOT expired) 
       -> Bitmap Index Scan on index_mos_active_1_on_type_id (cost=0.00..112.22 rows=5861 width=0) 
        Index Cond: (type_id = 34) 

complete SQL (실제 MOS 테이블 작성 이외의)

정말 뭔가를 놓치고 있는지 알고 싶습니다하거나 쿼리 플래너 문제입니다.

UPDATE : 내가 훨씬 간단한 예와 같은 문제를 재현 할 수 있었다, 두 테이블이 만료에 하나 개의 제약 조건을 기반으로 한 : 논리 값에 PostgreSQL의 제약 배제하지 않는에서 같은

CREATE TABLE mos (type_id INTEGER UNIQUE, expired boolean); 
CREATE TABLE mos_expired_1 (CHECK (expired = true )) INHERITS (mos); 
CREATE TABLE mos_active_1 (CHECK (expired = false)) INHERITS (mos); 
INSERT INTO mos_expired_1 (type_id,expired) VALUES(1, true); 
INSERT INTO mos_active_1 (type_id,expired) VALUES(2, false); 
EXPLAIN SELECT * from mos where expired = false; 
EXPLAIN SELECT * from mos where expired = true; 
+0

가장 최신 버전에서도 확실히 재현 할 수 있습니다. PostgreSQL 메일 링리스트에 질문 해보십시오. 아주 훌륭합니다. – rfusca

답변

1

같습니다 작업. integer 또는 enum을 사용할 때 제대로 작동합니다.

정수 :

CREATE TABLE mos (type_id INTEGER UNIQUE, expired int); 
CREATE TABLE mos_expired_1 (CHECK (expired = 0)) INHERITS (mos); 
CREATE TABLE mos_active_1 (CHECK (expired = 1)) INHERITS (mos); 
INSERT INTO mos_expired_1 (type_id,expired) VALUES(1, 0); 
INSERT INTO mos_active_1 (type_id,expired) VALUES(2, 1); 
analyze; 

EXPLAIN SELECT * from mos where expired = 0; 
           QUERY PLAN         
----------------------------------------------------------------------------- 
Result (cost=0.00..37.76 rows=12 width=8) 
    -> Append (cost=0.00..37.76 rows=12 width=8) 
     -> Seq Scan on mos (cost=0.00..36.75 rows=11 width=8) 
       Filter: (expired = 0) 
     -> Seq Scan on mos_expired_1 mos (cost=0.00..1.01 rows=1 width=8) 
       Filter: (expired = 0) 
(6 rows) 

EXPLAIN SELECT * from mos where expired = 1; 
           QUERY PLAN         
---------------------------------------------------------------------------- 
Result (cost=0.00..37.76 rows=12 width=8) 
    -> Append (cost=0.00..37.76 rows=12 width=8) 
     -> Seq Scan on mos (cost=0.00..36.75 rows=11 width=8) 
       Filter: (expired = 1) 
     -> Seq Scan on mos_active_1 mos (cost=0.00..1.01 rows=1 width=8) 
       Filter: (expired = 1) 
(6 rows) 

열거 :

CREATE TYPE mybool AS ENUM ('true', 'false');          
CREATE TABLE mos (type_id INTEGER UNIQUE, expired mybool); 
CREATE TABLE mos_expired_1 (CHECK (expired = 'true')) INHERITS (mos); 
CREATE TABLE mos_active_1 (CHECK (expired = 'false')) INHERITS (mos); 
INSERT INTO mos_expired_1 (type_id,expired) VALUES(1, 'true'); 
INSERT INTO mos_active_1 (type_id,expired) VALUES(2, 'false'); 
analyze; 

EXPLAIN SELECT * from mos where expired = 'true'; 
           QUERY PLAN         
----------------------------------------------------------------------------- 
Result (cost=0.00..37.76 rows=12 width=8) 
    -> Append (cost=0.00..37.76 rows=12 width=8) 
     -> Seq Scan on mos (cost=0.00..36.75 rows=11 width=8) 
       Filter: (expired = 'true'::mybool) 
     -> Seq Scan on mos_expired_1 mos (cost=0.00..1.01 rows=1 width=8) 
       Filter: (expired = 'true'::mybool) 
(6 rows) 

EXPLAIN SELECT * from mos where expired = 'false'; 
           QUERY PLAN         
---------------------------------------------------------------------------- 
Result (cost=0.00..37.76 rows=12 width=8) 
    -> Append (cost=0.00..37.76 rows=12 width=8) 
     -> Seq Scan on mos (cost=0.00..36.75 rows=11 width=8) 
       Filter: (expired = 'false'::mybool) 
     -> Seq Scan on mos_active_1 mos (cost=0.00..1.01 rows=1 width=8) 
       Filter: (expired = 'false'::mybool) 
(6 rows) 

이 버그 경우 나도 몰라. 나는 그것이 어디에도 기록되어 있지 않다고 생각한다.

+0

와우, 좋은 생각 나는 그 생각하지 않았다. postgresql 메일 링리스트에 같은 질문을 게시했습니다. 정말 버그인지 봅시다. – dsander