En Postgres, puede especificar una cláusula IN, como esta:
SELECT * FROM user WHERE id IN (1000, 1001, 1002)
¿Alguien sabe cuál es el número máximo de parámetros que puede pasar a IN?
postgresql
Alex Riley
fuente
fuente
PLAN DE CONSULTA
Pero si prueba la segunda consulta:
PLAN DE CONSULTA
Podemos ver que la tabla temporal de compilación de postgres y unirse con ella
fuente
No hay límite para la cantidad de elementos que está pasando a la cláusula IN. Si hay más elementos, lo considerará como una matriz y luego, para cada escaneo en la base de datos, verificará si está contenida en la matriz o no. Este enfoque no es tan escalable. En lugar de usar la cláusula IN, intente usar INNER JOIN con la tabla temporal. Consulte http://www.xaprb.com/blog/2006/06/28/why-large-in-clauses-are-problematic/ para obtener más información. El uso de escalas INNER JOIN y el optimizador de consultas pueden hacer uso de hash join y otras optimizaciones. Mientras que con la cláusula IN no hay forma de que el optimizador optimice la consulta. He notado una aceleración de al menos 2x con este cambio.
fuente
OR
yIN
cláusulas debido a la gran sobrecarga en el análisis y la planificación de tales consultas, no pude confirmar el problema con Postgres 9.5, vea esta respuesta .Como alguien más experimentado con Oracle DB, también estaba preocupado por este límite.
IN
Realicé una prueba de rendimiento para una consulta con ~ 10'000 parámetros en una lista, obteniendo números primos hasta 100'000 de una tabla con los primeros 100'000 enteros al enumerar todos los números primos como parámetros de consulta .Mis resultados indican que no debe preocuparse por sobrecargar el optimizador de planes de consulta u obtener planes sin uso de índice , ya que transformará la consulta para usarla
= ANY({...}::integer[])
donde pueda aprovechar los índices como se esperaba:Sin embargo, esto (bastante viejo) hilo en la lista de correo pgsql-hackers indica que todavía hay un costo no despreciable en la planificación de tales consultas, así que tome mi palabra con un poco de sal.
fuente
Si tiene una consulta como:
puede aumentar el rendimiento si reescribe su consulta como:
fuente
EXPLAIN
dice que está reescribiendo internamente miIN (...)
comoANY ('{...}'::integer[])
.Solo lo intenté. la respuesta es -> entero fuera de rango como un valor de 2 bytes: 32768
fuente
Es posible que desee considerar refactorizar esa consulta en lugar de agregar una lista arbitrariamente larga de identificadores ... Podría usar un rango si los identificadores siguen el patrón en su ejemplo:
Otra opción es agregar una selección interna:
fuente