w3schools mysql sql phpmyadmin query-optimization subquery

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.



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 en Null . Así que necesitas manejar eso también. Pero usando Exist , es simplemente un false . Mucho más fácil de hacer frente. Simply IN no puede comparar nada con Null pero Exists 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 del Count(*) para seleccionar TODAS las filas coincidentes basadas en el WHERE porque está comparando todos los valores.

Pero no olvides esto tampoco:

  • EXISTS ejecuta a alta velocidad contra IN : cuando los resultados de la subconsulta son muy grandes.
  • IN se adelanta a EXISTS : cuando los resultados de la subconsulta son muy pequeños.

Referencia a para más detalles: