Cuando se trata de bases de datos grandes, ¿cuál funciona mejor, IN
o OR
en el SQL Where
-clause?IN vs OR en el SQL WHERE Cláusula
¿Hay alguna diferencia en la forma en que se ejecutan?
Cuando se trata de bases de datos grandes, ¿cuál funciona mejor, IN
o OR
en el SQL Where
-clause?IN vs OR en el SQL WHERE Cláusula
¿Hay alguna diferencia en la forma en que se ejecutan?
Asumo 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 manual for MySQL si los valores son constantes IN
ordena la lista y luego utiliza una búsqueda binaria. Me imagino que OR
los evalúa uno por uno sin ningún orden en particular. Entonces IN
es más rápido en algunas circunstancias.
La mejor manera de saberlo es hacer un perfil en su base de datos con sus 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á indexado me dieron 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)
Así que en este caso el método que utiliza o está a punto de 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.
Si el optimizador vale la pena, deberían realizar lo mismo. –
@inflagranti: Desafortunadamente, no hay optimizador perfecto. Los optimizadores son programas extremadamente complejos y cada implementación tendrá sus propias fortalezas y debilidades. Es por eso que digo que deberías hacer un perfil de una implementación específica. Me imagino que la estructura extra del método 'IN' hace que sea más fácil de optimizar que un conjunto completo de cláusulas' OR' posiblemente relacionadas. Me sorprendería si hay un motor donde el método 'OR' es más rápido, pero no me sorprende que haya momentos en que O sea más lento. –
@MarkByers ¿No podría el optimizador siempre sustituir múltiples 'OR's con un' IN'? – mayu
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 tenga los índices necesarios.
La mejor manera de averiguarlo es mirando el plan de ejecución.
he probado con Oracle , y fue exactamente el mismo.
CREATE TABLE performance_test AS (SELECT * FROM dba_objects);
SELECT * FROM performance_test
WHERE object_name IN ('DBMS_STANDARD', 'DBMS_REGISTRY', 'DBMS_LOB');
A pesar de que la consulta utiliza IN
, el Plan de Ejecución dice que utiliza 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')
¿Qué sucede en Oracle si tiene más de 3 valores que está probando? ? ¿Sabes si Oracle no puede realizar la misma optimización de búsqueda binaria que MySQL o lo realiza en ambos casos? –
@Mark Byers: Intenté la misma consulta con 10 valores, el mismo resultado. Tenga en cuenta que el optimizador recurrió mis valores en orden alfabético. No me sorprendería si Oracle hiciera alguna optimización interna de ese filtro ... –
Oracle también tiene una operación 'INLIST ITERATOR', que seleccionaría si hubiera un índice que podría usar. Aún así, cuando lo probé, tanto 'IN' como 'OR' terminan con el mismo plan de ejecución. –
Creo que Oracle es lo suficientemente inteligente como para convertir el menos eficiente (cualquiera que sea) en el otro. Así que creo que la respuesta debería depender de la legibilidad de cada uno (donde creo que IN
claramente gana)
El operador OR necesita un proceso de evaluación mucho más complejo que el IN porque permite muchas condiciones, no solo equivale a EN.
Aquí hay un parecido de lo que puede usar con O pero que no son compatibles con IN: mayor. mayor o igual, menos, menos o igual, LIKE y algo más como el oráculo REGEXP_LIKE. Además, tenga en cuenta 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 = con 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.
[EDIT] Probablemente un optimizador no puede implementar optimiza en proceso de evaluación, pero esto no excluye que una vez que podría ocurrir (con una actualización de la versión de 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 uso en:
23.18ms
No es exactamente lo mismo, ya que ha utilizado una subconsulta para la cláusula IN. – gliljas
Mi primera conjetura sería que O se comporta mejor, a menos que el motor de SQL convierte en Into o detrás de la escena . ¿Has visto el plan de consulta de estos dos? – Raj
Posible duplicado de [rendimiento MYSQL OR vs IN] (http://stackoverflow.com/questions/782915/mysql-or-vs-in-performance) –