Для этого запроса:
SELECT t.entity_2_id, COUNT(*)
FROM tmp_table t
WHERE t.entity_1_id = 'cedca236-3f27-4db3-876c-a6c159f4d15e' AND
t.status <> 2 AND
t.entity_2_id = ANY (string_to_array('21c5598b-0620-4a8c-b6fd-a4bfee024254,af0f9cb9-da47-4f6b-a3c4-218b901842f7', ','))
GROUP BY t.entity_2_id;
Я бы порекомендовал индекс для tmp_table(entity_1_id, entity_2_id, status)
.
Однако вы можете найти это быстрее:
select rst.entity_2_id,
(select count(*)
from tmp_table t
where t.entity_2_id = rst.entity_2_id and
t.entity_1_id = 'cedca236-3f27-4db3-876c-a6c159f4d15e' AND
t.status <> 2
) as cnt
from regexp_split_to_table(str, ',') rst(entity_2_id);
Тогдавам нужен индекс для tmp_table(entity_2_id, entity_1_id, status)
.
В большинстве баз данных это будет быстрее, поскольку индекс является индексом покрытия, и это позволяет избежать окончательного агрегирования по всему набору результатов. Однако Postgres хранит информацию о блокировке на страницах данных, поэтому их все равно необходимо прочитать. Это все еще стоит попробовать.