Me pregunto si hay alguna diferencia en cuanto al rendimiento entre los siguientes
SELECT ... FROM ... WHERE someFIELD IN(1,2,3,4)
SELECT ... FROM ... WHERE someFIELD between 0 AND 5
SELECT ... FROM ... WHERE someFIELD = 1 OR someFIELD = 2 OR someFIELD = 3 ...
¿o MySQL optimizará el SQL de la misma manera que los compiladores optimizarán el código?
EDITAR: Cambió las AND
's a OR
' s por la razón indicada en los comentarios.
mysql
sql
performance
optimization
Scott
fuente
fuente
s I could say that it can also be converted to UNION
que se recomienda para reemplazar OR para optimizar la consulta.Respuestas:
Necesitaba saber esto con seguridad, así que comparé ambos métodos. Constantemente encontré
IN
que es mucho más rápido que usarOR
.No le crea a las personas que dan su "opinión", la ciencia se trata de pruebas y pruebas.
Ejecuté un bucle de 1000x las consultas equivalentes (por consistencia, usé
sql_no_cache
):IN
: 2.34969592094sOR
: 5.83781504631sActualización:
(No tengo el código fuente para la prueba original, ya que era hace 6 años, aunque devuelve un resultado en el mismo rango que esta prueba)
Para solicitar un código de muestra para probar esto, este es el caso de uso más simple posible. Usando Eloquent para simplificar la sintaxis, el equivalente de SQL sin procesar ejecuta lo mismo.
fuente
IN
declaración era aproximadamente un 30% más rápida que unaOR
.Do not believe people who give their "opinion"
Tienes 100% de razón, Stack Overflow desafortunadamente está lleno de ellosReturns 1 if expr is equal to any of the values in the IN list, else returns 0. If all values are constants, they are evaluated according to the type of expr and sorted. The search for the item then is done using a binary search. This means
IN is very quick if the IN value list consists entirely of constants
. Otherwise, type conversion takes place according to the rules described at Type Conversion, but applied to all the arguments.
IN
También hice una prueba para futuros Googlers. El recuento total de resultados devueltos es 7264 de 10000
Esta consulta tomó
0.1239
segundosEsta consulta tomó
0.0433
segundosIN
es 3 veces más rápido queOR
fuente
OR
: lo mejor es usar la expresión más compacta posible.La respuesta aceptada no explica la razón.
A continuación se citan MySQL de alto rendimiento, 3a edición.
fuente
Creo que ENTRE será más rápido ya que debería convertirse en:
Tengo entendido que un IN se convertirá en un montón de declaraciones OR de todos modos. El valor de IN es la facilidad de uso. (Ahorrar al tener que escribir cada nombre de columna varias veces y también hace que sea más fácil de usar con la lógica existente: no tiene que preocuparse por la precedencia AND / OR porque el IN es una declaración. Con un montón de declaraciones OR, tiene para asegurarse de rodearlos con paréntesis para asegurarse de que se evalúen como una condición).
La única respuesta real a su pregunta es PERFILAR SUS CONSULTAS . Entonces sabrá qué funciona mejor en su situación particular.
fuente
Depende de lo que está haciendo; qué tan amplio es el rango, cuál es el tipo de datos (sé que su ejemplo utiliza un tipo de datos numéricos, pero su pregunta también puede aplicarse a muchos tipos de datos diferentes).
Esta es una instancia en la que desea escribir la consulta en ambos sentidos; haz que funcione y luego usa EXPLAIN para descubrir las diferencias de ejecución.
Estoy seguro de que hay una respuesta concreta a esto, pero así es como, prácticamente hablando, averiguaría la respuesta para mi pregunta dada.
Esto podría ser de alguna ayuda: http://forge.mysql.com/wiki/Top10SQLPerformanceTips
Saludos,
Frank
fuente
Creo que una explicación a la observación de sunseeker es que MySQL realmente clasifica los valores en la declaración IN si son todos valores estáticos y usan búsqueda binaria, que es más eficiente que la alternativa OR simple. No recuerdo dónde lo leí, pero el resultado de Sunseeker parece ser una prueba.
fuente
Justo cuando pensabas que era seguro ...
¿Cuál es tu valor
eq_range_index_dive_limit
? En particular, ¿tiene más o menos elementos en laIN
cláusula?Esto no incluirá un Benchmark, pero se verá un poco en el funcionamiento interno. Usemos una herramienta para ver qué está sucediendo: Optimizer Trace.
La consulta:
SELECT * FROM canada WHERE id ...
Con un valor
OR
de 3 , parte de la traza se ve así:...
...
Tenga en cuenta cómo se está dando ICP
ORs
. Esto implica queOR
no está convertidoIN
, e InnoDB realizará un montón de=
pruebas a través de ICP. (No creo que valga la pena considerar MyISAM).(Este es el registro 5.6.22-71.0 de Percona;
id
es un índice secundario).Ahora para IN () con algunos valores
eq_range_index_dive_limit
= 10; Hay 8 valores....
...
Tenga en cuenta que
IN
no parece haberse convertido enOR
.Una nota al margen: tenga en cuenta que los valores constantes se ordenaron . Esto puede ser beneficioso de dos maneras:
Finalmente, IN () con muchos valores
...
...
Nota al margen: necesitaba esto debido al volumen de la traza:
fuente
O será el más lento. Si IN o BETWEEN es más rápido dependerá de sus datos, pero esperaría que BETWEEN sea más rápido normalmente, ya que puede tomar un rango de un índice (suponiendo que algún campo esté indexado).
fuente
A continuación se detallan 6 consultas utilizando MySQL 5.6 @SQLFiddle
En resumen, las 6 consultas cubren columnas indexadas independientemente y se usaron 2 consultas por tipo de datos. Todas las consultas resultaron en el uso de un índice independientemente de IN () u OR que se estén utilizando.
Realmente solo quería desacreditar las declaraciones hechas que OR significa que no se puede usar ningún índice. Esto no es verdad Los índices se pueden usar en consultas usando OR como se muestran las 6 consultas en los siguientes ejemplos.
También me parece que muchos han ignorado el hecho de que IN () es un acceso directo de sintaxis para un conjunto de OR. A pequeña escala, las diferencias de rendimiento entre el uso de IN () -v- OR son extremadamente (infinitamente) marginales.
Mientras que a mayor escala, IN () es ciertamente más conveniente, pero lógicamente equivale a un conjunto de condiciones OR. Cambio de circunstancias para cada consulta, por lo que probar su consulta en sus tablas siempre es lo mejor.
Resumen de los 6 planes explicativos, todos "Uso de condición de índice" (desplácese hacia la derecha)
Violín de SQL
Configuración del esquema MySQL 5.6 :
.
Consulta 1 :
Resultados :
Consulta 2 :
Resultados :
Consulta 3 :
Resultados :
Consulta 4 :
Resultados :
Consulta 5 :
Resultados :
Consulta 6 :
Resultados :
fuente
Apuesto a que son iguales, puedes hacer una prueba haciendo lo siguiente:
repita el "in (1,2,3,4)" 500 veces y vea cuánto tarda. recorra la versión "= 1 o = 2 o = 3 ..." 500 veces y vea cuánto tiempo dura.
También podría intentar unirse, si someField es un índice y su tabla es grande, podría ser más rápido ...
Probé el método de combinación anterior en mi SQL Server y es casi lo mismo que en in (1,2,3,4), y ambos resultan en una búsqueda de índice agrupado. No estoy seguro de cómo MySQL los manejará.
fuente
2018 : IN (...) es más rápido. Pero > = && <= es incluso más rápido que IN .
Aquí está mi punto de referencia .
fuente
Por lo que entiendo sobre la forma en que el compilador optimiza este tipo de consultas, el uso de la cláusula IN es más eficiente que las cláusulas OR múltiples. Si tiene valores en los que se puede usar la cláusula BETWEEN, aún es más eficiente.
fuente
Sé que, siempre que tenga un índice en Field, BETWEEN lo usará para encontrar rápidamente un extremo y luego lo atravesará. Esto es lo más eficiente.
Cada EXPLICACIÓN que he visto muestra que "IN (...)" y "... OR ..." son intercambiables e igualmente (in) eficientes. Lo que cabría esperar, ya que el optimizador no tiene forma de saber si comprenden o no un intervalo. También es equivalente a UNION ALL SELECT en los valores individuales.
fuente
Como explicaron otros, IN se elige mejor que OR con respecto al rendimiento de la consulta.
Las consultas con condición OR pueden tardar más tiempo de ejecución en los siguientes casos.
fuente