exists mysql w3schools
Subconsultas con EXISTS vs IN-MySQL (5)
Debajo de dos consultas hay subconsultas. Ambos son iguales y ambos funcionan bien para mí. Pero el problema es que la consulta del Método 1 tarda aproximadamente 10 segundos en ejecutarse, mientras que la consulta del Método 2 tarda menos de 1 segundo.
Pude convertir la consulta del método 1 al método 2, pero no entiendo lo que sucede en la consulta. He estado tratando de averiguarlo yo mismo. Realmente me gustaría saber cuál es la diferencia entre las siguientes dos consultas y cómo se produce el aumento de rendimiento. ¿Cuál es la lógica detrás de esto?
Soy nuevo en estas técnicas avanzadas. Espero que alguien me ayude aquí. Dado que leí los docs que no me dan una pista.
Método 1 :
SELECT
*
FROM
tracker
WHERE
reservation_id IN (
SELECT
reservation_id
FROM
tracker
GROUP BY
reservation_id
HAVING
(
method = 1
AND type = 0
AND Count(*) > 1
)
OR (
method = 1
AND type = 1
AND Count(*) > 1
)
OR (
method = 2
AND type = 2
AND Count(*) > 0
)
OR (
method = 3
AND type = 0
AND Count(*) > 0
)
OR (
method = 3
AND type = 1
AND Count(*) > 1
)
OR (
method = 3
AND type = 3
AND Count(*) > 0
)
)
Método 2:
SELECT
*
FROM
`tracker` t
WHERE
EXISTS (
SELECT
reservation_id
FROM
`tracker` t3
WHERE
t3.reservation_id = t.reservation_id
GROUP BY
reservation_id
HAVING
(
METHOD = 1
AND TYPE = 0
AND COUNT(*) > 1
)
OR
(
METHOD = 1
AND TYPE = 1
AND COUNT(*) > 1
)
OR
(
METHOD = 2
AND TYPE = 2
AND COUNT(*) > 0
)
OR
(
METHOD = 3
AND TYPE = 0
AND COUNT(*) > 0
)
OR
(
METHOD = 3
AND TYPE = 1
AND COUNT(*) > 1
)
OR
(
METHOD = 3
AND TYPE = 3
AND COUNT(*) > 0
)
)
El método 2 es rápido porque utiliza el operador EXISTS
, donde MySQL
no carga ningún resultado. Como se mencionó en el enlace de sus docs , también se omite lo que haya en la cláusula SELECT
. Solo comprueba el primer valor que coincide con el criterio, una vez que lo encuentra, establece la condición TRUE
y se mueve para un procesamiento posterior.
En el otro lado, el Método 1 tiene un operador IN
que carga todos los valores posibles y luego los compara. La condición se establece en TRUE
solo cuando se encuentra una coincidencia exacta, lo que requiere mucho tiempo.
Por lo tanto su método 2 es rápido.
Espero eso ayude...
El operador EXISTS es un operador booleano que devuelve verdadero o falso. El operador EXISTS a menudo se usa en una subquery para probar una condición de " existencia ".
SELECT
select_list
FROM
a_table
WHERE
[NOT] EXISTS(subquery);
Si la subconsulta devuelve una fila, el operador EXISTS devuelve verdadero; de lo contrario, devuelve falso.
Además, el operador EXISTS termina el procesamiento adicional inmediatamente una vez que encuentra una fila coincidente. Debido a esta característica, puede utilizar el operador EXISTS para mejorar el rendimiento de la consulta en algunos casos.
El operador NOT niega el operador EXISTS . En otras palabras, NOT EXISTS devuelve verdadero si la subconsulta no devuelve ninguna fila, de lo contrario, devuelve falso.
Puede utilizar SELECT * , la columna SELECT , SELECT a_constant o cualquier cosa en la subconsulta. Los resultados son los mismos porque MySQL ignora la lista de selección que aparece en la cláusula SELECT .
La razón es que el operador EXISTS trabaja en base al principio de "al menos encontrado". Devuelve verdadero y detiene la exploración de la tabla una vez que se encuentra al menos una fila coincidente.
Por otro lado, cuando el operador IN se combina con una subconsulta, MySQL debe procesar la subconsulta primero y luego usa el resultado de la subconsulta para procesar la consulta completa.
La regla general es que si la subconsulta contiene un gran volumen de datos, el operador EXISTS proporciona un mejor rendimiento.
Sin embargo, la consulta que utiliza el operador IN se realizará más rápido si el conjunto de resultados devuelto por la subconsulta es muy pequeño.
Para explicaciones detalladas y ejemplos: MySQL EXISTS - mysqltutorial.org
El segundo método es más rápido porque tienes esto como "DONDE t3.reservation_id = t.reservation_id". En el primer caso, su subconsulta debe realizar un escaneo completo en la tabla para verificar la información. Sin embargo, en el Método 2o, la subconsulta sabe exactamente lo que está buscando y una vez que se encuentra, se verifica la condición de tener.
Su Documentación Oficial. Optimización de SubQuery con Existe
Un Explain Plan
te hubiera mostrado por qué exactamente debes usar Exists
. Por lo general, la pregunta es Exists vs Count(*)
. Exists
es más rápido. ¿Por qué?
Con respecto a los desafíos presentes por NULL: cuando la subconsulta devuelve
Null
, para IN la consulta completa se convierte enNull
. Así que necesitas manejar eso también. Pero usandoExist
, es simplemente unfalse
. Mucho más fácil de hacer frente. SimplyIN
no puede comparar nada conNull
peroExists
puede.ej.
Exists (Select * from yourtable where bla = ''blabla'');
se obtiene verdadero / falso en el momento en que se encuentra / empareja un golpe .En este caso,
IN
toma la posición delCount(*)
para seleccionar TODAS las filas coincidentes basadas en elWHERE
porque está comparando todos los valores.
Pero no olvides esto tampoco:
-
EXISTS
ejecuta a alta velocidad contraIN
: cuando los resultados de la subconsulta son muy grandes. -
IN
se adelanta aEXISTS
: cuando los resultados de la subconsulta son muy pequeños.
Referencia a para más detalles: