J'ai une table partitionnée par deux colonnes, expired
et type_id
. expired
est une partition booléenne et type_id
par gamme. Tableau: ExemplesLes contraintes de partition PostgreSQL se comportent étrangement
mos_active_1
...
mos_active_15
mos_expired_1
...
mos_expired_15
Mes contraintes sont définies comme ceci:
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)
Si je cours maintenant tout comme prévu SELECT * from mos WHERE expired = true AND type_id = 34
fonctionne, juste mos_expired_1
est touché.
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 enought SELECT * from mos WHERE expired = false AND type_id = 34
ne fait pas travail. EXPLAIN
révèle que mos_expired_1
et mos_active_1
sont interrogés.
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 (en plus de la création de la table mos réelle)
Je voudrais vraiment savoir si je manque quelque chose ou c'est un problème de planificateur de requêtes.
MISE À JOUR: j'ai pu reproduire le même problème avec un exemple beaucoup plus simple, deux tables ayant une contrainte basées sur expirés:
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;
Je peux certainement reproduire, même sur la version la plus récente. Essayez de demander sur la liste de diffusion PostgreSQL, ils sont très très bons. – rfusca