Vaše další dva indexy nebudou fungovat jednoduše proto, že ->>
operátor vrátí text
, zatímco zjevně máte jsonb
třídy operátorů gin na mysli. Upozorňujeme, že zmiňujete pouze json
, ale ve skutečnosti potřebujete jsonb
pro pokročilé možnosti indexování.
Chcete-li vypracovat nejlepší strategii indexování, budete muset přesněji definovat, které dotazy pokrýt. Zajímají vás pouze krávy? Nebo všechna zvířata / všechny značky? Kteří operátoři jsou možní? Obsahuje váš dokument JSON také jiné než zvířecí klíče? Co s nimi dělat? Chcete do indexu zahrnout řádky, kde se krávy (nebo cokoli jiného) v dokumentu JSON vůbec nezobrazují?
Za předpokladu:
- Zajímají nás pouze krávy na první úrovni hnízdění.
- Hodnota je vždy platné
integer
. - Nezajímají nás řádky bez krav.
Navrhuji funkční index btree, podobně jako vy, ale převeďte hodnotu na integer
. Nepředpokládám, že byste chtěli, aby bylo srovnání hodnoceno jako text
(kde '2' je větší než '1111').
CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int)); -- !
Další sada závorek je vyžadována pro přetypovanou zkratku, aby byla syntaxe pro výraz indexu jednoznačná.
Použijte stejný výraz ve svých dotazech, aby si Postgres uvědomil, že index je použitelný:
SELECT * FROM farm WHERE (animal ->> 'cow')::int > 3;
Pokud potřebujete obecnější jsonb
index, zvažte:
- Jaký je správný index pro dotazování struktur v polích v Postgres jsonb?
Pro známé, statické, triviální počet zvířat (jak jsi komentoval), navrhuji dílčí indexy jako:
CREATE INDEX animal_index ON farm (((animal ->> 'cow')::int))
WHERE (animal ->> 'cow') IS NOT NULL;
CREATE INDEX animal_index ON farm (((animal ->> 'chicken')::int))
WHERE (animal ->> 'chicken') IS NOT NULL;
atd.
Možná budete muset do dotazu přidat podmínku indexu:
SELECT * FROM farm
WHERE (animal ->> 'cow')::int > 3
AND (animal ->> 'cow') IS NOT NULL;
Může se zdát nadbytečné, ale může být nezbytné. Otestujte pomocí ANALYZE
!