S hstore jsem nikdy nehrál, ale dělám něco podobného, když potřebuji sloupec EAV, např.:
create index on product_eav (eav_value) where (eav_type = 'int');
Omezením je, že ve svém dotazu musíte být explicitní, abyste jej mohli použít, tj. tento dotaz nebude používat výše uvedený index:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size;
Ale tohle by:
select product_id
from product_eav
where eav_name = 'size'
and eav_value = :size
and type = 'int';
Ve vašem příkladu by to mělo být pravděpodobně více jako:
create index on product ((data->'size')::int) where (data->'size' is not null);
To by se mělo vyhnout přidání odkazu na index, když není uvedena žádná velikost. V závislosti na verzi PG, kterou používáte, může být nutné dotaz upravit takto:
select product_id
from products
where data->'size' is not null
and data->'size' = :size;
Dalším velkým rozdílem mezi běžným a částečným indexem je to, že druhý nemůže vynutit jedinečné omezení v definici tabulky. To se podaří:
create unique index foo_bar_key on foo (bar) where (cond);
Následující nebudou:
alter table foo add constraint foo_bar_key unique (bar) where (cond);
Ale tohle bude:
alter table foo add constraint foo_bar_excl exclude (bar with =) where (cond);