Има два варианта на IN изрази:
expression IN (subquery)expression IN (value [, ...])
По същия начин, два варианта с ANY конструкция:
expression operator ANY (subquery)expression operator ANY (array expression)
Подзаявката работи и за двете техники, но за втората форма на всеки, IN очаква списък със стойности (както е дефинирано в стандартния SQL), докато = ANY очаква масив .
Кое да използвам?
ANY е по-късно, по-гъвкаво допълнение, може да се комбинира с всеки двоичен оператор, връщащ булева стойност. IN изгаря до специален случай на ANY . Всъщност втората му форма е пренаписана вътрешно:
IN се пренаписва с = ANY NOT IN се пренаписва с <> ALL
Проверете EXPLAIN изход за всяка заявка, за да видите сами. Това доказва две неща:
INникога не може да бъде по-бърз от= ANY.= ANYняма да бъде значително по-бързо.
Изборът трябва да се реши откакво е по-лесно за предоставяне :списък със стойности или масив (евентуално като литерал на масива - една стойност).
Ако идентификаторите, които ще предадете, идватот БДа така или иначе е много по-ефективно да ги изберете директно (подзаявка) или да интегрирате изходната таблица в заявката с JOIN (харесвам @mu коментира).
За да преминете дълъг списък на стойностите от вашия клиент и получете най-доброто производителност , използвайте масив, unnest() и се присъединете или го предоставете като табличен израз с помощта на VALUES (като коментира @PinnyM). Но имайте предвид, че JOIN запазва възможни дубликати в предоставения масив / задайте докато IN или = ANY Недей. Още:
- Оптимизиране на заявка в Postgres с голям IN
При наличие на NULL стойности, NOT IN често е грешен избор и NOT EXISTS би било правилно (и по-бързо):
- Изберете редове, които не присъстват в друга таблица
Синтаксис за = ANY
За израза на масива Postgres приема:
- конструктор на масив (масивът е конструиран от списък със стойности от страната на Postgres) във формата:
ARRAY[1,2,3] - или литерал на масив от формата
'{1,2,3}'.
За да избегнете невалидни прехвърляния на тип, можете да предавате изрично:
ARRAY[1,2,3]::numeric[]
'{1,2,3}'::bigint[]
Свързано:
- PostgreSQL:Проблем с предаването на масив към процедура
- Как да предам масив от персонализиран тип на функцията Postgres
Или можете създайте функция Postgres, като вземете VARIADIC параметър, който приема отделни аргументи и формира масив от тях:
- Предаване на множество стойности в един параметър
Как да предам масива от Ruby?
Ако приемем id да бъде integer :
MyModel.where('id = ANY(ARRAY[?]::int[])', ids.map { |i| i})
Но аз просто се занимавам с Ruby. @mu предоставя подробни инструкции в този свързан отговор:
- Изпращате ли масив от стойности към sql заявка в ruby?