Ваша первоначальная попытка верна, но вам нужно использовать (частичные) индексы btree и растровые индексы, чтобы полагаться на них:
create index on product(((ext->'size')::int)) where ((ext->'size') is not null);
То же самое для массы, и если планировщик не получает это на месте, добавьте два предложения where, то есть where ext->'size' is not null
и то же самое для массы.
Если есть какой-то шаблон (который, вероятно, так как большинство продуктов с размером также имеют массу), потенциально создайте многоколонный индекс, объединяющий два - один мешочек, другой деск.
Индекс джина, как вы его написали, вместе с сопровождающим запросом (с синтаксической ошибкой) в основном будут делать то же самое, но неупорядоченно; это будет медленнее.