En todas las empresas en las que he trabajado, he descubierto que la gente todavía está escribiendo sus consultas SQL en el estándar ANSI-89:
select a.id, b.id, b.address_1
from person a, address b
where a.id = b.id
en lugar del estándar ANSI-92:
select a.id, b.id, b.address_1
from person a
inner join address b
on a.id = b.id
Para una consulta extremadamente simple como esta, no hay una gran diferencia en la legibilidad, pero para consultas grandes, encuentro que tener mis criterios de combinación agrupados con la lista de la tabla hace que sea mucho más fácil ver dónde podría tener problemas en mi combinación, y déjeme mantener todo mi filtrado en mi cláusula WHERE. Sin mencionar que creo que las combinaciones externas son mucho más intuitivas que la sintaxis (+) en Oracle.
Mientras trato de evangelizar ANSI-92 a la gente, ¿hay algún beneficio de rendimiento concreto al usar ANSI-92 sobre ANSI-89? Lo probaría por mi cuenta, pero las configuraciones de Oracle que tenemos aquí no nos permiten usar EXPLAIN PLAN, no querría que la gente intentara optimizar su código, ¿verdad?
Respuestas:
Según "SQL Performance Tuning" de Peter Gulutzan y Trudy Pelzer, de las seis u ocho marcas de RDBMS que probaron, no hubo diferencia en la optimización o el rendimiento de las uniones de estilo SQL-89 frente a SQL-92. Se puede suponer que la mayoría de los motores RDBMS transforman la sintaxis en una representación interna antes de optimizar o ejecutar la consulta, por lo que la sintaxis legible por humanos no hace ninguna diferencia.
También trato de evangelizar la sintaxis SQL-92. Dieciséis años después de su aprobación, ¡ya es hora de que la gente comience a usarlo! Y todas las marcas de bases de datos SQL ahora lo admiten, por lo que no hay razón para seguir utilizando la
(+)
sintaxis no estándar de Oracle o la sintaxis de*=
Microsoft / Sybase.En cuanto a por qué es tan difícil romper con la comunidad de desarrolladores del hábito SQL-89, solo puedo asumir que hay una gran "base de la pirámide" de programadores que codifican copiando y pegando, utilizando ejemplos antiguos de libros, artículos de revistas, u otra base de código, y estas personas no aprenden la nueva sintaxis de forma abstracta. Algunas personas hacen coincidir patrones y otras aprenden de memoria.
Sin embargo, gradualmente veo que la gente usa la sintaxis SQL-92 con más frecuencia de lo que solía hacerlo. He estado respondiendo preguntas de SQL en línea desde 1994.
fuente
Bueno, el estándar ANSI092 incluye una sintaxis bastante atroz. Las uniones naturales son una y la cláusula USING es otra. En mi humilde opinión, la adición de una columna a una tabla no debería romper el código, pero un NATURAL JOIN se rompe de la manera más atroz. La "mejor" forma de romper es mediante un error de compilación. Por ejemplo, si SELECCIONA * en algún lugar, la adición de una columna podríafallar al compilar. La siguiente mejor forma de fallar sería un error de tiempo de ejecución. Es peor porque sus usuarios pueden verlo, pero aún así le da una buena advertencia de que ha roto algo. Si usa ANSI92 y escribe consultas con combinaciones NATURALES, no se interrumpirá en el tiempo de compilación y no se interrumpirá en el tiempo de ejecución, la consulta comenzará de repente a producir resultados incorrectos. Este tipo de errores son insidiosos. Los informes salen mal, la divulgación potencialmente financiera es incorrecta.
Para aquellos que no están familiarizados con NATURAL Joins. Unen dos tablas en cada nombre de columna que existe en ambas tablas. Lo que es realmente genial cuando tienes una clave de 4 columnas y estás harto de escribirla. El problema surge cuando Table1 tiene una columna preexistente llamada DESCRIPTION y agrega una nueva columna a Table2 llamada, oh, no sé, algo inofensivo como, mmm, DESCRIPTION y ahora está uniendo las dos tablas en un VARCHAR2 (1000) campo que es de forma libre.
La cláusula USING puede conducir a una ambigüedad total además del problema descrito anteriormente. En otra publicación de SO , alguien mostró este ANSI-92 SQL y pidió ayuda para leerlo.
Esto es completamente ambiguo. Puse una columna de ID de usuario en las tablas de empresas y usuarios y no hay ninguna queja. ¿Qué sucede si la columna UserID en las empresas es la ID de la última persona que modificó esa fila?
Lo digo en serio, ¿alguien puede explicar por qué era necesaria tanta ambigüedad? ¿Por qué está integrado directamente en el estándar?
Creo que Bill tiene razón en que hay una gran base de desarrolladores que copian y pegan a través de la codificación. De hecho, puedo admitir que soy uno de ellos cuando se trata de ANSI-92. Cada ejemplo que vi mostraba múltiples combinaciones anidadas entre paréntesis. Honestamente, eso hace que elegir las tablas en el sql sea difícil en el mejor de los casos. Pero luego un evangilista de SQL92 explicó que en realidad forzaría una orden de unión. JESÚS ... todos esos correctores de copias que he visto ahora están forzando una orden de unión, un trabajo que es mejor dejar en el 95% del tiempo a los optimizadores especialmente una copia / empacadora.
Tomalak lo hizo bien cuando dijo:
Tiene que darme algo y no veo ninguna ventaja. Y si hay una ventaja, los aspectos negativos son un albatros demasiado grande para ser ignorado.
fuente
SELECT *
(luego descubriendo que el cliente se basa en el orden de campo) - Se siente un poco descuidadoAlgunas razones me vienen a la mente:
Por mi parte, hago todas mis combinaciones en la sintaxis SQL-92 y convierto el código donde puedo. Es la forma más limpia, legible y potente de hacerlo. Pero es difícil convencer a alguien de que use el nuevo estilo, cuando cree que le duele en términos de más trabajo de escritura sin cambiar el resultado de la consulta.
fuente
En respuesta a la publicación NATURAL JOIN y USING anterior.
¿POR QUÉ alguna vez vería la necesidad de usarlos? No estaban disponibles en ANSI-89 y se agregaron para ANSI-92 como lo que solo puedo ver como un atajo.
Nunca dejaría una combinación al azar y siempre especificaría la tabla / alias y la identificación.
Para mí, el único camino a seguir es ANSI-92. Es más detallado y la sintaxis no es del agrado de los seguidores de ANSI-89, pero separa claramente tus UNIONES de tu FILTRADO.
fuente
Primero déjeme decir que en SQL Server la sintaxis de unión externa (* =) no da resultados correctos todo el tiempo. Hay ocasiones en las que lo interpreta como una combinación cruzada y no como una combinación externa. Entonces, hay una buena razón para dejar de usarlo. Y esa sintaxis de unión externa es una característica obsoleta y no estará en la próxima versión de SQL Server después de SQL Server 2008. Aún podrá hacer las combinaciones internas, pero ¿por qué diablos querría alguien hacerlo? No son claros y mucho más difíciles de mantener. No es fácil saber qué es parte de la combinación y qué es realmente la cláusula where.
Una de las razones por las que creo que no debería utilizar la sintaxis antigua es que comprender las uniones y lo que hacen y lo que no hacen es un paso fundamental para cualquiera que escriba código SQL. No debe escribir ningún código SQL sin comprender a fondo las combinaciones. Si los comprende bien, probablemente llegará a la conclusión de que la sintaxis ANSI-92 es más clara y fácil de mantener. Nunca conocí a un experto en SQL que no usara la sintaxis ANSI-92 con preferencia a la sintaxis anterior.
La mayoría de las personas que he conocido o con las que he tratado que usan el código antiguo, realmente no entienden las combinaciones y, por lo tanto, se meten en problemas al consultar la base de datos. Esta es mi experiencia personal, así que no digo que siempre sea cierto. Pero como especialista en datos, he tenido que arreglar demasiado de esta basura a lo largo de los años para no creerlo.
fuente
Me enseñaron ANSI-89 en la escuela y trabajé en la industria durante algunos años. Luego dejé el fabuloso mundo de DBMS durante 8 años. Pero luego regresé y me enseñaron este nuevo material de ANSI 92. He aprendido la sintaxis Join On y ahora enseño SQL y recomiendo la nueva sintaxis JOIN ON.
Pero la desventaja que veo es que las subconsultas correlacionadas no parecen tener sentido a la luz de las uniones ANSI 92. Cuando la información de unión se incluyó en el DÓNDE y las subconsultas correlacionadas se "unieron" en el DÓNDE, todo parecía correcto y coherente. En ANSI 92, los criterios de combinación de tablas no están en el DONDE y la subconsulta "combinación" sí, la sintaxis parece inconsistente. Por otro lado, intentar "arreglar" esta inconsistencia probablemente lo empeoraría.
fuente
No sé la respuesta con seguridad ... esta es una guerra religiosa (aunque en menor grado que Mac-Pc u otros)
Una conjetura es que hasta hace relativamente poco, Oracle (y tal vez otros proveedores también) no adoptó el estándar ANSI-92 (creo que estaba en Oracle v9, más o menos) y, por lo tanto, para los desarrolladores de DBA / Db que trabajan en empresas que todavía estaban usando estas versiones, (o querían que el código fuera portátil a través de los servidores que podrían estar usando estas versiones, tenían que ceñirse al antiguo estándar ...
Realmente es una pena, porque la nueva sintaxis de unión es mucho más legible y la sintaxis anterior genera resultados incorrectos (incorrectos) en varios escenarios bien documentados.
fuente
INNER JOIN
en 1995, aunqueLEFT JOIN
no hasta 1996. MySQL lo ha admitido al menos desde 3.23, lanzado en 1999; PostgreSQL al menos desde 7.2, lanzado en 2002. Algunas búsquedas ocasionales en Google no me dan ninguna respuesta para Teradata.Inercia y practicidad.
ANSI-92 SQL es como escribir al tacto. De alguna manera teórica, podría mejorar todo algún día, pero ahora puedo escribir mucho más rápido mirando las teclas con cuatro dedos. Necesitaría retroceder para avanzar, sin ninguna garantía de que alguna vez haya una recompensa.
Escribir SQL es aproximadamente el 10% de mi trabajo. Si necesito ANSI-92 SQL para resolver un problema que ANSI-89 SQL no puede resolver, lo usaré. (De hecho, lo uso en Access). Si usarlo todo el tiempo me ayudara a resolver mis problemas existentes mucho más rápido, dedicaría tiempo a asimilarlo. Pero puedo sacar ANSI-89 SQL sin pensar en la sintaxis. Me pagan por resolver problemas; pensar en la sintaxis SQL es una pérdida de tiempo y del dinero de mi empleador.
Algún día, joven Grasshopper, defenderá su uso de la sintaxis SQL ANSI-92 contra los jóvenes que se quejan de que debería usar SQL3 (o lo que sea). Y entonces lo entenderás. :-)
fuente
Tenía una consulta que se escribió originalmente para SQL Server 6.5, que no admitía la sintaxis de unión SQL 92, es decir
en cambio fue escrito como
La consulta había existido por un tiempo, y los datos relevantes se habían acumulado para hacer que la consulta se ejecutara demasiado lento, unos 90 segundos para completarse. Para cuando surgió este problema, nos habíamos actualizado a SQL Server 7.
Después de jugar con índices y otras acciones de Pascua, cambié la sintaxis de unión para que sea compatible con SQL 92. El tiempo de consulta se redujo a 3 segundos.
Hay una buena razón para cambiar.
Reubicado desde aquí .
fuente
Puedo responder desde el punto de vista de un desarrollador promedio, sabiendo lo suficiente de SQL para comprender ambas sintaxis, pero aún buscando en Google la sintaxis exacta de insertar cada vez que lo necesito ... :-P (No hago SQL todo el día , simplemente solucionando algunos problemas de vez en cuando).
Bueno, en realidad, encuentro la primera forma más intuitiva, sin una jerarquía aparente entre las dos tablas. El hecho de que aprendí SQL con libros posiblemente antiguos, mostrando el primer formulario, probablemente no ayude ... ;-)
Y la primera referencia que encuentro en un sql select búsqueda de en Google (que devuelve principalmente respuestas en francés para mí ... ) primero muestra la forma anterior (luego explica la segunda).
Solo dando algunas pistas sobre la pregunta "por qué" ... ^ _ ^ Debería leer un buen libro moderno (independiente de DB) sobre el tema. Si alguien tiene sugerencias ...
fuente
No puedo hablar por todas las escuelas, pero en mi universidad, cuando estábamos haciendo el módulo SQL de nuestro curso, no enseñaban ANSI-92, enseñaban ANSI-89, ¡en un viejo sistema VAX! No estuve expuesto a ANSI-92 hasta que comencé a investigar en Access después de haber creado algunas consultas utilizando el diseñador de consultas y luego profundizando en el código SQL. Al darme cuenta de que no tenía idea de cómo estaba completando las combinaciones, o las implicaciones de la sintaxis, comencé a profundizar más para poder entenderlo.
Dado que la documentación disponible no es exactamente intuitiva en muchos casos, y que las personas tienden a ceñirse a lo que saben y, en muchos casos, no se esfuerzan por aprender más de lo que necesitan para hacer su trabajo, es Es fácil ver por qué la adopción está tardando tanto.
Por supuesto, están aquellos evangelistas técnicos a los que les gusta jugar y entender, y tienden a ser los que adoptan los principios "más nuevos" y tratan de convertir al resto.
Curiosamente, me parece que muchos programadores salen de la escuela y dejan de avanzar; pensando que porque esto es lo que les enseñaron, así es como se hace. No es hasta que te quitas las anteojeras que te das cuenta de que la escuela solo estaba destinada a enseñarte lo básico y darte suficiente comprensión para aprender el resto por ti mismo y que en realidad apenas rascaste la superficie de lo que hay que saber; ahora es tu trabajo continuar ese camino.
Por supuesto, esa es solo mi opinión basada en mi experiencia.
fuente
1) Forma estándar de escribir OUTER JOIN, versus * = o (+) =
2) UNIÓN NATURAL
3) Depende del motor de la base de datos, ANSI-92 tiende a ser más óptimo.
4) Optimización manual:
Digamos que tenemos la siguiente sintaxis (ANSI-89):
Podría escribirse como:
Pero también como:
Todos ellos (1), (2), (3) devuelven el mismo resultado, sin embargo están optimizados de manera diferente, depende del motor de la base de datos pero la mayoría lo hace:
5) Las consultas más largas son menos complicadas.
fuente
Razones por las que la gente usa ANSI-89 a partir de mi experiencia práctica con programadores y aprendices jóvenes y viejos y recién graduados:
Personalmente, prefiero ANSI-92 y cambio cada consulta que veo en la sintaxis ANSI-89 a veces solo para comprender mejor la declaración SQL en cuestión. Pero me di cuenta de que la mayoría de las personas con las que trabajo no tienen la habilidad suficiente para escribir combinaciones en muchas tablas. Codifican lo mejor que pueden y usan lo que memorizaron la primera vez que encontraron una declaración SQL.
fuente
Aquí hay algunos puntos que comparan SQL-89 y SQL-92 y aclaran algunos conceptos erróneos en otras respuestas.
NATURAL JOINS
son una idea horrible. Están implícitos y requieren metainformación sobre la tabla. Nada acerca de SQL-92 requiere su uso, así que simplemente ignórelos . No son relevantes para esta discusión.USING
es una gran idea, tiene dos efectos:id
en ambas tablas. Después de unir las tablas, esto se vuelve ambiguo y requiere un alias explícito. Además,id
es casi seguro que las s en la combinación tenían datos diferentes. Si une una persona a otra, ahora debe asignar un alias a unoid
aperson_id
y unoid
acompany_id
, sin el cual la combinación produciría dos columnas ambiguas. El uso de un identificador único global para la clave sustituta de la tabla es la convención con la que se obtienen las recompensas estándarUSING
.CROSS JOIN
. ACROSS JOIN
no reduce el conjunto, lo aumenta implícitamente.FROM T1,T2
es lo mismo queFROM T1 CROSS JOIN T2
, que produce una combinación cartesiana que normalmente no es lo que desea. Tener la selectividad para reducir eso eliminado a una distanciaWHERE
condicional significa que es más probable que cometa errores durante el diseño.,
explícitos SQL-89 y SQL-92JOIN
tienen diferente precedencia.JOIN
tiene una precedencia más alta. Peor aún, algunas bases de datos como MySQL se equivocaron durante mucho tiempo. . Así que mezclar los dos estilos es una mala idea, y el estilo mucho más popular hoy en día es el estilo SQL-92.fuente
Oracle no implementa ANSI-92 del todo bien. He tenido varios problemas, sobre todo porque las tablas de datos en Oracle Apps están muy bien dotadas de columnas. Si el número de columnas en sus combinaciones supera las 1050 columnas (lo cual es muy fácil de hacer en Apps), obtendrá este error falso que no tiene ningún sentido lógico:
Reescribir la consulta para usar la sintaxis de unión de estilo antiguo hace que el problema desaparezca, lo que parece señalar con el dedo de la culpa directamente a la implementación de las combinaciones ANSI-92.
Hasta que encontré este problema, fui un firme promotor de ASNI-92, debido a los beneficios de reducir la posibilidad de una unión cruzada accidental, que es demasiado fácil de hacer con la sintaxis de estilo antiguo.
Ahora, sin embargo, me resulta mucho más difícil insistir en ello. Señalan la mala implementación de Oracle y dicen "Lo haremos a nuestra manera, gracias".
fuente
Un nuevo estándar SQL hereda todo del estándar anterior, también conocido como "los grilletes de la compatibilidad". Por lo tanto, el estilo de unión 'antiguo' / 'separado por comas' / 'no calificado' es una sintaxis SQL-92 perfectamente válida.
Ahora, sostengo que SQL-92
NATURAL JOIN
es la única combinación que necesita. Por ejemplo, sostengo que es superior ainner join
porque no genera columnas duplicadas, no más variables de rango enSELECT
cláusulas para eliminar la ambigüedad de las columnas! Pero no puedo esperar cambiar todos los corazones y mentes, por lo que necesito trabajar con programadores que continuarán adoptando lo que personalmente considero estilos de unión heredados (¡e incluso pueden referirse a las variables de rango como 'alias'!). Esta es la naturaleza del trabajo en equipo y no operar en el vacío.Una de las críticas al lenguaje SQL es que se puede obtener el mismo resultado usando una serie de sintaxis semánticamente equivalentes (algunas usan álgebra relacional, otras usan cálculo relacional), donde elegir la 'mejor' simplemente se reduce al estilo personal . Así que me siento tan cómodo con las uniones de 'estilo antiguo' como con las que estoy
INNER
. Si me tomaría el tiempo para reescribirlosNATURAL
depende del contexto.fuente