Nigdy nie grałem z hstore, ale robię coś podobnego, gdy potrzebuję kolumny EAV, np.:
create index on product_eav (eav_value) where (eav_type = 'int');
Ograniczenie w tym zakresie polega na tym, że aby z niego skorzystać, konieczne jest wyraźne określenie w zapytaniu, tj. to zapytanie nie skorzystałoby z powyższego indeksu:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size;
Ale ten:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size
and type = 'int';
W twoim przykładzie powinno to wyglądać bardziej następująco:
create index on product ((data->'size')::int) where (data->'size' is not null);
Powinno to uniknąć dodawania odwołania do indeksu, gdy nie ma wpisu rozmiaru. W zależności od używanej wersji PG zapytanie może wymagać modyfikacji w następujący sposób:
select product_id
from products
where data->'size' is not null
and data->'size' = :size;
Inną dużą różnicą między indeksem zwykłym a częściowym jest to, że ten ostatni nie może wymusić ograniczenia unikatowego w definicji tabeli. To się powiedzie:
create unique index foo_bar_key on foo (bar) where (cond);
Poniższe nie będą:
alter table foo add constraint foo_bar_key unique (bar) where (cond);
Ale to spowoduje:
alter table foo add constraint foo_bar_excl exclude (bar with =) where (cond);