¿Las consultas JOIN son más rápidas que varias consultas? (Ejecutas tu consulta principal, y luego ejecutas muchos otros SELECT basados en los resultados de tu consulta principal)
Lo pregunto porque UNIRSE a ellos complicaría MUCHO el diseño de mi aplicación
Si son más rápidos, ¿alguien puede aproximarse más o menos por cuánto? Si es 1.5x, no me importa, pero si es 10x, supongo que sí.
mysql
database
join
query-optimization
Thomas Bonini
fuente
fuente
Respuestas:
Esto es demasiado vago para darle una respuesta relevante a su caso específico. Depende de muchas cosas. Jeff Atwood (fundador de este sitio) en realidad escribió sobre esto . Sin embargo, en su mayor parte, si tiene los índices correctos y realiza correctamente sus uniones, generalmente será más rápido hacer 1 viaje que varios.
fuente
Para las uniones internas, una única consulta tiene sentido, ya que solo obtiene filas coincidentes. Para las uniones izquierdas, las consultas múltiples son mucho mejores ... mira el siguiente punto de referencia que hice:
Consulta única con 5 uniones
consulta: 8.074508 segundos
tamaño del resultado: 2268000
5 consultas seguidas
tiempo de consulta combinado: 0.00262 segundos
tamaño del resultado: 165 (6 + 50 + 7 + 12 + 90)
.
Tenga en cuenta que obtenemos los mismos resultados en ambos casos (6 x 50 x 7 x 12 x 90 = 2268000)
las uniones izquierdas usan exponencialmente más memoria con datos redundantes.
Es posible que el límite de memoria no sea tan malo si solo hace una combinación de dos tablas, pero generalmente tres o más y vale la pena realizar consultas diferentes.
Como nota al margen, mi servidor MySQL está justo al lado de mi servidor de aplicaciones ... por lo que el tiempo de conexión es insignificante. Si su tiempo de conexión es en segundos, entonces quizás haya un beneficio
Franco
fuente
Esta pregunta es antigua, pero le faltan algunos puntos de referencia. Comparé JOIN contra sus 2 competidores:
WHERE IN(...)
o equivalenteEl resultado es claro: en MySQL,
JOIN
es mucho más rápido. Las consultas N + 1 pueden reducir drásticamente el rendimiento de una aplicación:Es decir, a menos que seleccione muchos registros que apunten a un número muy pequeño de registros extranjeros distintos. Aquí hay un punto de referencia para el caso extremo:
Es muy poco probable que esto suceda en una aplicación típica, a menos que se una a una relación de muchos, en cuyo caso la clave externa está en la otra tabla, y está duplicando los datos de la tabla principal muchas veces.
Para llevar:
JOIN
Vea mi artículo en Medium para más información.
fuente
De hecho, llegué a esta pregunta buscando una respuesta, y después de leer las respuestas dadas, solo puedo estar de acuerdo en que la mejor manera de comparar el rendimiento de las consultas DB es obtener números del mundo real porque solo hay que tener en cuenta muchas variables PERO, también creo que comparar los números entre ellos no sirve de nada en casi todos los casos. Lo que quiero decir es que los números siempre deben compararse con un número aceptable y definitivamente no compararse entre sí.
Puedo entender si una forma de consulta lleva unos 0.02 segundos y la otra toma 20 segundos, esa es una gran diferencia. Pero, ¿qué sucede si una forma de consulta tarda 0.0000000002 segundos y la otra tarda 0.0000002 segundos? En ambos casos, una forma es la friolera 1000 veces más rápida que la otra, pero ¿ realmente sigue siendo "feroz" en el segundo caso?
En pocas palabras, como lo veo personalmente: si funciona bien, busque la solución fácil.
fuente
Hice una prueba rápida seleccionando una fila de una tabla de 50,000 filas y uniéndola con una fila de una tabla de 100,000 filas. Básicamente se parecía a:
vs
Los dos métodos de selección tomaron 3.7 segundos para 50,000 lecturas, mientras que JOIN tardó 2.0 segundos en mi computadora lenta en casa. INNER JOIN y LEFT JOIN no hicieron la diferencia. Obtener varias filas (por ejemplo, usando IN SET) arrojó resultados similares.
fuente
La verdadera pregunta es: ¿Estos registros tienen una relación uno a uno o una relación uno a muchos ?
Respuesta TLDR:
Si es uno a uno, use una
JOIN
declaración.Si es uno a muchos, use una (o muchas)
SELECT
declaraciones con optimización de código del lado del servidor.Por qué y cómo usar SELECT para la optimización
SELECT
'ing (con múltiples consultas en lugar de uniones) en un gran grupo de registros basado en una relación uno a muchos produce una eficiencia óptima, ya queJOIN
' ing tiene un problema de pérdida de memoria exponencial. Tome todos los datos, luego use un lenguaje de script del lado del servidor para resolverlos:Resultados:
Aquí, obtengo todos los registros, en una declaración de selección. Es mejor que
JOIN
obtener un pequeño grupo de estos registros, uno a la vez, como un subcomponente de otra consulta. Luego lo analizo con un código del lado del servidor que se parece a ...Cuándo no usar JOIN para la optimización
JOIN
'formar un gran grupo de registros basado en una relación uno a uno con un solo registro produce una eficiencia óptima en comparación con múltiplesSELECT
declaraciones, una tras otra, que simplemente obtienen el siguiente tipo de registro.Pero
JOIN
es ineficiente cuando se obtienen registros con una relación de uno a muchos.Ejemplo: la base de datos Blogs tiene 3 tablas de interés, Blogpost, Tag y Comment.
Si hay 1 blogpost, 2 etiquetas y 2 comentarios, obtendrá resultados como:
Observe cómo se duplica cada registro. Bien, entonces, 2 comentarios y 2 etiquetas son 4 filas. ¿Qué pasa si tenemos 4 comentarios y 4 etiquetas? No obtienes 8 filas, obtienes 16 filas:
Agregue más tablas, más registros, etc., y el problema se inflará rápidamente a cientos de filas que están llenas de datos en su mayoría redundantes.
¿Cuánto te cuestan estos duplicados? Memoria (en el servidor SQL y el código que intenta eliminar los duplicados) y recursos de red (entre el servidor SQL y su servidor de código).
Fuente: https://dev.mysql.com/doc/refman/8.0/en/nested-join-optimization.html ; https://dev.mysql.com/doc/workbench/en/wb-relationship-tools.html
fuente
Construya consultas y uniones separadas, luego cronometre cada una de ellas; nada ayuda más que los números del mundo real.
Entonces, aún mejor: agregue "EXPLICAR" al comienzo de cada consulta. Esto le indicará cuántas subconsultas está utilizando MySQL para responder a su solicitud de datos y cuántas filas escaneadas para cada consulta.
fuente
Dependiendo de la complejidad de la base de datos en comparación con la complejidad del desarrollador, puede ser más sencillo hacer muchas llamadas SELECT.
Intente ejecutar algunas estadísticas de la base de datos contra JOIN y SELECTS múltiples. Vea si en su entorno JOIN es más rápido / lento que SELECT.
Por otra parte, si cambiarlo a JOIN significaría un día / semana / mes adicional de trabajo de desarrollo, me quedaría con varios SELECT
Salud,
BLT
fuente
En mi experiencia, descubrí que generalmente es más rápido ejecutar varias consultas, especialmente al recuperar grandes conjuntos de datos.
Al interactuar con la base de datos desde otra aplicación, como PHP, existe el argumento de un viaje al servidor sobre muchos.
Hay otras formas de limitar la cantidad de viajes realizados al servidor y aún ejecutar múltiples consultas que a menudo no solo son más rápidas sino que también hacen que la aplicación sea más fácil de leer, por ejemplo mysqli_multi_query.
No soy un novato cuando se trata de SQL, creo que hay una tendencia para los desarrolladores, especialmente los juniors, a pasar mucho tiempo tratando de escribir uniones muy inteligentes porque se ven inteligentes, mientras que en realidad hay formas inteligentes de extraer datos que se ven sencillo.
El último párrafo fue una opinión personal, pero espero que esto ayude. Sin embargo, estoy de acuerdo con los demás, que dicen que debe comparar. Ningún enfoque es una bala de plata.
fuente
Si debe usar una combinación es ante todo si una combinación tiene sentido . Solo en ese punto es el rendimiento incluso algo a tener en cuenta, ya que casi todos los demás casos darán lugar a un rendimiento significativamente peor .
Las diferencias de rendimiento dependerán en gran medida de cuán relacionada esté la información que está consultando. Se une al trabajo, y son rápidos cuando los datos están relacionados y se indexan correctamente, pero a menudo generan redundancia y, a veces, más resultados de los necesarios. Y si sus conjuntos de datos no están directamente relacionados, pegarlos en una sola consulta dará como resultado lo que se llama un producto cartesiano (básicamente, todas las combinaciones posibles de filas), que casi nunca es lo que desea.
Esto a menudo es causado por relaciones de muchos a uno a muchos. Por ejemplo, la respuesta de HoldOffHunger mencionó una sola consulta para publicaciones, etiquetas y comentarios. Los comentarios están relacionados con una publicación, al igual que las etiquetas ... pero las etiquetas no están relacionadas con los comentarios.
En este caso, es inequívocamente mejor que esto sea al menos dos consultas separadas. Si intenta unir etiquetas y comentarios, porque no hay una relación directa entre los dos, terminará con todas las combinaciones posibles de etiqueta y comentario.
many * many == manymany
. Aparte de eso, dado que las publicaciones y las etiquetas no están relacionadas, puede hacer esas dos consultas en paralelo, lo que lleva a una ganancia potencial.Sin embargo, consideremos un escenario diferente: desea los comentarios adjuntos a una publicación y la información de contacto de los comentaristas.
Aquí es donde debes considerar unirte. Además de ser una consulta mucho más natural, la mayoría de los sistemas de bases de datos (incluido MySQL) tienen muchas personas inteligentes que realizan mucho trabajo duro para optimizar consultas como esta. Para consultas separadas, dado que cada consulta depende de los resultados de la anterior, las consultas no se pueden hacer en paralelo, y el tiempo total se convierte no solo en el tiempo de ejecución real de las consultas, sino también en el tiempo dedicado a buscar resultados, tamizar a través de ellos para obtener ID para la siguiente consulta, vincular filas, etc.
fuente
¿Será más rápido en términos de rendimiento? Probablemente. Pero también potencialmente bloquea más objetos de base de datos a la vez (dependiendo de su base de datos y su esquema) y, por lo tanto, disminuye la concurrencia. En mi experiencia, la gente a menudo se confunde con el argumento de "menos viajes de ida y vuelta a la base de datos" cuando en realidad en la mayoría de los sistemas OLTP donde la base de datos está en la misma LAN, el cuello de botella real rara vez es la red.
fuente
Aquí hay un enlace con 100 consultas útiles, estas se prueban en la base de datos Oracle, pero recuerde que SQL es un estándar, lo que difiere entre Oracle, MS SQL Server, MySQL y otras bases de datos es el dialecto SQL:
http://javaforlearn.com/100-sql-queries-learn/
fuente
Hay varios factores que significa que no hay una respuesta binaria. La cuestión de qué es lo mejor para el rendimiento depende de su entorno. Por cierto, si su selección única con un identificador no es inferior a un segundo, algo puede estar mal con su configuración.
La verdadera pregunta que debe hacerse es cómo desea acceder a los datos. Single selecciona soporte de enlace tardío. Por ejemplo, si solo desea información de los empleados, puede seleccionar de la tabla Empleados. Las relaciones de clave externa se pueden utilizar para recuperar recursos relacionados en un momento posterior y según sea necesario. Las selecciones ya tendrán una clave para señalar, por lo que deben ser extremadamente rápidas, y solo tiene que recuperar lo que necesita. La latencia de la red siempre debe tenerse en cuenta.
Las uniones recuperarán todos los datos a la vez. Si está generando un informe o completando una cuadrícula, esto puede ser exactamente lo que desea. Las uniones compiladas y optimizadas simplemente serán más rápidas que las selecciones individuales en este escenario. Recuerde, las uniones ad-hoc pueden no ser tan rápidas: debe compilarlas (en un proceso almacenado). La respuesta rápida depende del plan de ejecución, que detalla exactamente qué pasos toma el DBMS para recuperar los datos.
fuente
Sí, una consulta usando JOINS sería más rápida. Aunque sin conocer las relaciones de las tablas que está consultando, el tamaño de su conjunto de datos o dónde están las claves principales, es casi imposible decir cuánto más rápido.
¿Por qué no probar ambos escenarios? Entonces sabrás con seguridad ...
fuente