expired
및 type_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
는 하지 작업을 수행합니다. EXPLAIN
은 mos_expired_1
및 mos_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;
가장 최신 버전에서도 확실히 재현 할 수 있습니다. PostgreSQL 메일 링리스트에 질문 해보십시오. 아주 훌륭합니다. – rfusca