В Postgres вы можете указать предложение IN, например:
SELECT * FROM user WHERE id IN (1000, 1001, 1002)
Кто-нибудь знает, какое максимальное количество параметров вы можете передать в IN?
postgresql
Алекс Райли
источник
источник
QUERY PLAN
Но если попробовать второй запрос:
QUERY PLAN
Мы видим, что postgres создает временную таблицу и присоединяется к ней
источник
Количество элементов, передаваемых в предложение IN, не ограничено. Если имеется больше элементов, он будет рассматривать его как массив, а затем для каждого сканирования в базе данных будет проверять, содержится ли он в массиве или нет. Этот подход не так масштабируем. Вместо использования предложения IN попробуйте использовать INNER JOIN с временной таблицей. Для получения дополнительной информации см. Http://www.xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic/ . Использование весов INNER JOIN также позволяет оптимизатору запросов использовать хеш-соединение и другие способы оптимизации. В то время как с предложением IN оптимизатор не может оптимизировать запрос. Я заметил ускорение по крайней мере в 2 раза с этим изменением.
источник
OR
иIN
предложений из-за больших накладных расходов при разборе и планировании таких запросов, я не смог подтвердить проблему с Postgres 9.5, см. Этот ответ .Как человек с большим опытом работы с БД Oracle, я тоже был обеспокоен этим ограничением. Я выполнил тест производительности для запроса с ~ 10 000 параметров в
IN
-листе, выбирая простые числа до 100 000 из таблицы с первыми 100 000 целыми числами , фактически перечисляя все простые числа в качестве параметров запроса .Мои результаты показывают, что вам не нужно беспокоиться о перегрузке оптимизатора планов запросов или получении планов без использования индексов , поскольку он преобразует запрос для использования
= ANY({...}::integer[])
там, где он может использовать индексы, как и ожидалось:Однако этот (довольно старый) поток в списке рассылки pgsql-hackers указывает на то, что при планировании таких запросов все еще есть немалая цена, так что поверьте мне на слово.
источник
Если у вас есть запрос, как:
Вы можете повысить производительность, если переписать свой запрос, например:
источник
EXPLAIN
говорит, что внутренне переписывает мойIN (...)
asANY ('{...}'::integer[])
.Только что попробовал. ответ -> целое число вне диапазона в виде 2-байтового значения: 32768
источник
Вы можете рассмотреть возможность рефакторинга этого запроса вместо добавления произвольно длинного списка идентификаторов ... Вы можете использовать диапазон, если идентификаторы действительно следуют шаблону в вашем примере:
Другой вариант - добавить внутренний выбор:
источник