Las siguientes consultas SQL son las mismas:
SELECT column1, column2
FROM table1, table2
WHERE table1.id = table2.id;
SELECT column1, column2
FROM table1 JOIN table2
ON table1.id = table2.id;
Y ciertamente da como resultado los mismos planes de consulta en cada DBMS que he probado.
Pero de vez en cuando, leo o escucho una opinión de que uno es definitivamente mejor que el otro. Naturalmente, estas afirmaciones nunca se justifican con una explicación.
Donde trabajo, la segunda versión parece ser favorecida por la mayoría de los otros desarrolladores, por lo que también tiendo a ese estilo para minimizar la sorpresa. Pero en mi corazón, realmente estoy pensando en el primero (ya que así es como lo aprendí originalmente).
¿Es una de estas formas objetivamente mejor que la otra? Si no, ¿cuáles serían las razones para usar una sobre la otra?
sql
coding-style
SingleNegationElimination
fuente
fuente
Respuestas:
Encuentro que la segunda forma es mejor. Puede ser porque así lo aprendí, lo admito, pero tengo una razón concreta: la separación de las preocupaciones. Poner los campos que está utilizando para unir las tablas en la cláusula where puede generar dificultades para comprender las consultas.
Por ejemplo, tome la siguiente consulta:
La consulta anterior tiene condiciones de unión de tabla y condiciones de lógica de negocios reales, todas combinadas en un solo espacio. Con una consulta grande, esto puede ser muy difícil de entender.
Sin embargo, ahora tome este código:
En este caso, todo lo que tenga que ver con las tablas o cómo se relacionan está aislado de la cláusula from, mientras que la lógica comercial real para la restricción de consultas está en la cláusula where. Creo que eso es mucho más comprensible, particularmente para consultas más grandes.
fuente
La sintaxis de unión reemplazó a la antigua sintaxis de coma en 1992. Actualmente no hay ninguna razón para escribir código con la sintaxis de coma. No gana nada y está sujeto a algunos problemas que simplemente no tiene con la sintaxis explícita.
En primer lugar, a medida que obtiene consultas más complicadas, es muy fácil hacer una unión cruzada accidental al perder una condición where. Esto es algo que la sintaxis de unión explícita puede evitar que ocurra, ya que obtendrá un error de sintaxis.
Si tiene la intención de una unión cruzada, la sintaxis de unión explícita lo dejará claro, mientras que en la sintaxis implícita alguien que realiza mantenimiento puede asumir que olvidó agregar la cláusula where.
Luego está el problema de las uniones izquierda y derecha que son problemáticas en al menos algunos dbs que usan la sintaxis implícita. Están en desuso en SQL Server y, de hecho, no devuelven resultados correctos incluso en las versiones anteriores. Ninguna consulta que necesite una combinación externa debe contener la sintaxis implícita en SQL Server.
Además, he visto preguntas aquí y en otros sitios donde ocurrieron resultados incorrectos cuando las personas mezclan las uniones implícitas y explícitas (al agregar una combinación izquierda, por ejemplo), por lo que es una mala idea mezclarlas.
Finalmente, muchas personas que usan combinaciones implícitas en realidad no entienden las combinaciones. Esta es una comprensión crítica que debe tener para consultar efectivamente una base de datos.
fuente
Decir ah. Simplemente encontré una posible respuesta a mi propia pregunta, mientras miraba la documentación de PostgreSQL . Para resumir lo que explica esta página, la consulta resultante sigue siendo la misma, pero la cantidad de planes que el optimizador debe considerar aumenta exponencialmente con la cantidad de uniones.
Después de aproximadamente seis de tales uniones, el número es tan grande que el tiempo para planificar la consulta puede ser notable, y después de alrededor de diez, el optimizador cambiará de una búsqueda exhaustiva de planes a una búsqueda probabilística, y puede no llegar al plan óptimo. .
Al establecer un parámetro de tiempo de ejecución, puede indicarle al planificador que trate las uniones internas y cruzadas mencionadas explícitamente de manera diferente a las uniones implícitas, forzándolas a la parte superior del plan y sin explorar otras opciones.
Es de destacar que el comportamiento predeterminado es el mismo en cualquier caso, y que obtener planes alternativos requiere conocer los aspectos internos de dbms y las peculiaridades de las tablas en cuestión para obtener un resultado diferente
fuente
Bueno, aquí está la visión de la teoría de conjuntos:
Cuando usa una coma para separar dos (o más) nombres de tablas, lo que pretende es el producto cartesiano. Cada fila de la tabla 'izquierda' se 'emparejará' (concatenará) con la de la tabla derecha.
Ahora, si escribe algo en la cláusula where, es como poner una condición en esta 'concatenación' que indica qué filas 'concatenar' con qué filas.
En realidad, esto es "unir" las filas :) y, por lo tanto, la palabra clave de unión que ayuda a proporcionar una sintaxis más legible y es más comprensible que 'realmente' quiera unirse en algunos valores comunes. Similar a lo que @Dustin ha aclarado anteriormente.
Ahora, cada DBMS es inteligente, es decir, no calcula el producto cartesiano primero y luego filtra los datos (extremadamente derrochador), sino que lo hace en función de la estructura de la consulta. Lo único en lo que puedo pensar es que cuando le pides que se una, es como hacer explícita la actividad de unión y probablemente ayude a ejecutar el código más rápido (¿por cuánto? Tendrás que perfilarlo y verlo) pero en el caso separado por comas, necesita algo de tiempo para "descubrir" la estrategia óptima. Puedo estar equivocado, pero solo estoy haciendo una suposición educada sobre cómo se codificaría ...
fuente
Creo que generalmente es mejor usar declaraciones JOIN para ese caso.
Si, en el futuro, surge una situación que requiere cambiar la declaración de una UNIÓN INTERNA a una UNIÓN EXTERNA, será mucho más fácil hacerlo con la segunda declaración.
fuente
Cualquier RDBMS hará que sean lo mismo en términos de ejecución. Se trata de si uno es más legible y expresivo.
Use JOIN para que quede claro qué es la combinación de combinaciones y qué es la selección real, como en:
vs.
El último caso deja en claro de inmediato cuál es la condición de unión y cuál es el criterio de selección.
fuente
Solo una vez he visto los dos resultados en un conjunto diferente de optimizaciones y si la memoria sirve, estaba en ms-sql2k en una consulta realmente complicada. En ese ejemplo, la forma anterior utilizada con * = resultó en un rendimiento aproximadamente 4 veces más rápido. Nadie, incluidos nuestros técnicos de Microsoft, podría explicar por qué. Los chicos de MS lo etiquetaron como un error. Nunca lo he vuelto a ver.
Dado que la mayoría de los RDBMS son lo suficientemente inteligentes como para no hacer los cartesianos completos, la razón más grande por la que puedo pensar en no usarlo (además de que se deprecia) es que la mayoría de las personas menores de 30-35 años con las que he trabajado nunca han visto forma anterior antes y perderse terriblemente cuando lo encuentran.
fuente
El viejo estilo ha quedado en desuso, no debes usarlo.
Ni siquiera debería haber una discusión sobre cuál es mejor o no. El nuevo código no debería usar la sintaxis anterior.
fuente
Una razón para la sintaxis más concisa es que es más concisa, por lo que si te sientes cómodo es más fácil de leer. Creo que el caso detallado es similar a escribir aritmética en COBOL, por ejemplo, MULTIPLICAR A POR B DANDO C.
fuente