Как наиболее эффективно переписать большое предложение IN?

Я написал API, используя go и gorm, который выполняет вычисления в нашей базе данных и возвращает результаты.

Я только что достиг предела параметра для условия IN при использовании агрегата. Пример запроса:

SELECT SUM(total_amount) from Table where user_id in(...70k parameters) group by user_id

Один из моих текущих пограничных случаев имеет> 65535 идентификаторов пользователей, поэтому мой клиент Postgres выдает ошибку:

got 66037 parameters but PostgreSQL only supports 65535 parameters

Я не уверен, как лучше всего подойти к этому. Тот, который будет обрабатывать большое количество параметров для этого пограничного случая, не влияя на мой типичный вариант использования. Должен ли я разбивать идентификаторы и повторять несколько запросов, сохраняя их в памяти, пока у меня не будут все данные, которые мне нужны? Используйте ANY(VALUES)...

Очевидно, что из запроса у меня очень ограниченные знания о Postgres, поэтому любая помощь будет невероятно оценена.


person Jay Lane    schedule 09.10.2018    source источник
comment
вы создаете таблицу с нужным вам user_id и выполняете левое соединение   -  person citynorman    schedule 09.10.2018


Ответы (1)


Вы можете заменить user_id IN (value [, ...]) одним из:

user_id IN (subquery)
user_id = ANY (subquery)
user_id = ANY (array expression)

Ни подзапросы, ни массивы не имеют такого же ограничения. Самый короткий синтаксис ввода будет таким:

user_id = ANY ('{1,2,3}'::int[])  -- make array type match type of user_id

Подробности и дополнительные параметры:

Или вы можете создать (временную) таблицу tmp_usr(user_id int), импортировать в нее, возможно, с помощью SQL COPY или psql \copy вместо INSERT для лучшей производительности с очень большими наборами, а затем < em>присоединиться к таблице, например:

SELECT SUM(total_amount)
FROM   tbl
JOIN   tmp_usr USING (user_id)
GROUP  BY user_id;

Кстати, GROUP BY user_id без включения user_id в список SELECT выглядит подозрительно. Может быть упрощенный пример запроса.

person Erwin Brandstetter    schedule 09.10.2018
comment
Присоединение к предложению значений вместо IN — еще один вариант, который иногда также быстрее. См., например. здесь - person a_horse_with_no_name; 09.10.2018
comment
Да, выражение VALUES — это одна из форм подзапроса, и обычно это быстрее для больших наборов. Вариация на тему: передать массив и unnest в подзапросе. Информация и ссылка на дополнительную информацию для каждого в связанном ответе выше. - person Erwin Brandstetter; 10.10.2018