query lista ejemplos datos consultas comandos clausulas basico sql database

lista - IN vs OR en la cláusula SQL WHERE



select sql (6)

Cuando se trata de grandes bases de datos, que tiene un mejor rendimiento, IN u OR en el SQL Where -clause?

¿Hay alguna diferencia en la forma en que se ejecutan?


Creo que Oracle es lo suficientemente inteligente como para convertir el menos eficiente (lo que sea) en el otro. Así que creo que la respuesta debería depender de la legibilidad de cada uno (donde creo que IN gana claramente)


El operador OR necesita un proceso de evaluación mucho más complejo que el constructo IN porque permite muchas condiciones, no solo equivale a IN.

Aquí hay un ejemplo de lo que puede usar con O pero que no es compatible con IN: mayor. mayor o igual, menos, menos o igual, LIKE y algo más como el oráculo REGEXP_LIKE. Además, considere que las condiciones no siempre pueden comparar el mismo valor.

Para el optimizador de consultas es más fácil administrar el operador IN porque es solo una construcción que define el operador OR en múltiples condiciones con = operador en el mismo valor. Si utiliza el operador OR, el optimizador puede no considerar que siempre está utilizando el operador = en el mismo valor y, si no realiza una elaboración más profunda y mucho más compleja, probablemente podría excluir que solo haya = operadores para los mismos valores en todas las condiciones involucradas, con la consecuente exclusión de métodos de búsqueda optimizados como la búsqueda binaria ya mencionada.

[EDITAR] Probablemente un optimizador no implemente un proceso de evaluación IN optimizado, pero esto no excluye que podría ocurrir una vez (con una actualización de la versión de la base de datos). Por lo tanto, si usa el operador OR, la elaboración optimizada no se usará en su caso.


Hice una consulta SQL en una gran cantidad de OR (350). Postgres hacerlo 437.80ms .

Ahora usa IN:

23.18ms


La mejor forma de averiguarlo es mirando el plan de ejecución.

Lo intenté con Oracle , y fue exactamente lo mismo.

CREATE TABLE performance_test AS ( SELECT * FROM dba_objects ); SELECT * FROM performance_test WHERE object_name IN (''DBMS_STANDARD'', ''DBMS_REGISTRY'', ''DBMS_LOB'' );

Aunque la consulta usa IN , el plan de ejecución dice que usa OR :

-------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 8 | 1416 | 163 (2)| 00:00:02 | |* 1 | TABLE ACCESS FULL| PERFORMANCE_TEST | 8 | 1416 | 163 (2)| 00:00:02 | -------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("OBJECT_NAME"=''DBMS_LOB'' OR "OBJECT_NAME"=''DBMS_REGISTRY'' OR "OBJECT_NAME"=''DBMS_STANDARD'')


Supongo que quiere saber la diferencia de rendimiento entre los siguientes:

WHERE foo IN (''a'', ''b'', ''c'') WHERE foo = ''a'' OR foo = ''b'' OR foo = ''c''

De acuerdo con el manual de MySQL, si los valores son constantes IN ordena la lista y luego utiliza una búsqueda binaria. Me imagino que OR evalúa uno por uno sin ningún orden en particular. Entonces IN es más rápido en algunas circunstancias.

La mejor forma de saberlo es hacer un perfil de tu base de datos con tus datos específicos para ver cuál es más rápido.

Intenté ambos en un MySQL con 1000000 filas. Cuando la columna está indexada, no hay una diferencia discernible en el rendimiento; ambas son casi instantáneas. Cuando la columna no está indexada obtuve estos resultados:

SELECT COUNT(*) FROM t_inner WHERE val IN (1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000); 1 row fetched in 0.0032 (1.2679 seconds) SELECT COUNT(*) FROM t_inner WHERE val = 1000 OR val = 2000 OR val = 3000 OR val = 4000 OR val = 5000 OR val = 6000 OR val = 7000 OR val = 8000 OR val = 9000; 1 row fetched in 0.0026 (1.7385 seconds)

Entonces, en este caso, el método que usa OR es aproximadamente un 30% más lento. Agregar más términos hace la diferencia más grande. Los resultados pueden variar en otras bases de datos y en otros datos.


OR tiene sentido (desde el punto de vista de la legibilidad), cuando hay menos valores para comparar. IN es útil esp. cuando tienes una fuente dinámica, con la cual quieres que se comparen los valores.

Otra alternativa es usar un JOIN con una tabla temporal.
No creo que el rendimiento sea un problema, siempre que tengas los índices necesarios.