2011-02-15 17 views
6

me gustaría confirmar que la consulta SQL¿El orden de las tablas en una unión importa, cuando se usan las uniones IZQUIERDAS (externas)?

SELECT .... 
    FROM apples, 
     oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id, 
     bananas 
WHERE .... 

es exactamente equivalente a otras permutaciones en el FROM subcláusula, como

SELECT .... 
    FROM oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id, 
     bananas, 
     apples 
WHERE .... 

o

SELECT .... 
    FROM bananas, 
     apples, 
     oranges 
     LEFT JOIN kiwis ON kiwis.orange_id = oranges.id 
WHERE .... 

siempre que la explícita LEFT JOIN, entre naranjas y kiwis, permanece intacto. Por lo que he leído en varios documentos, el conjunto devuelto debe ser exactamente el mismo.

Realmente solo me preocupan los resultados de la consulta, no su rendimiento en una base de datos real. (Estoy usando PostgreSQL 8.3, que AFAIK no admite sugerencias del optimizador sobre el orden de unión, y tratará de crear un plan de consulta óptimo automáticamente).

+0

¿Lo has probado? El orden de 'JOIN' s es irrelevante a menos que necesite resultados específicos del anterior' JOIN'' – Matthew

+0

¿Los plátanos, las manzanas y las naranjas son un producto cartesiano? ¿O la cláusula "join-in-WHERE"? – gbn

+1

EXPLAIN le mostrará: http://www.postgresql.org/docs/current/static/sql-explain.html Y no hay ningún motivo para insinuar nada, PostgreSQL es bastante inteligente. –

Respuesta

15

Es lo mismo, pero ambiguo como el infierno con el implícita CROSS JOINs. Use uniones explícitas

Si se une a la cláusula WHERE, los resultados pueden diferir porque las uniones y los filtros están mezclados.

SELECT .... 
    FROM apples a 
     JOIN 
     bananas b ON ... 
     JOIN 
     oranges o ON ... 
     LEFT JOIN 
     kiwis k ON k.orange_id = o.id 
WHERE (filters only) 

Notas:

  • combinaciones internas y Cross se une al son conmutativa y asociativa: orden no importa por lo general.
  • OUTER JOINS no lo son, lo que ha identificado
  • SQL es declarativo: le dice al optimizador lo que quiere, no cómo hacerlo. Esto elimina las consideraciones de orden de JOIN (sujeto a los 2 artículos anteriores)
+0

Una respuesta muy buena y completa, gracias. Para el registro, sí, las condiciones de unión están en la cláusula WHERE. Esta es una aplicación heredada, y estoy en proceso de refactorizar algunas de las consultas. –

0

He hecho SQL para burros durante años, y en mi experiencia, el orden de las tablas no importa. La base de datos examinará la consulta como un todo y creará el plan de consulta óptimo. Es por eso que las compañías de bases de datos emplean a muchas personas con doctorado en optimización de planes de consulta.

El proveedor de la base de datos cometería un suicidio comercial si lo optimizara en el orden en que enumeró personalmente el SQL en su consulta.

+1

Las versiones anteriores de DBMS en realidad lo hacían de esa manera (por ejemplo, Oracle 7 y 8).Esto generalmente se llamaba un "optimizador basado en reglas" ya que miraba estáticamente la consulta y aplicaba algunas reglas basadas en la estructura de la consulta para determinar el plan de ejecución. Con un optimizador basado en reglas, la primera tabla usualmente era la tabla de manejo, por lo que la orden tuvo una gran influencia en el rendimiento. –

1

La situación se resume en Controlling the Planner with Explicit JOIN Clauses. Las uniones externas no se reordenan, las internas pueden serlo. Y puede forzar un orden particular de optimizador al eliminar * join_collapse_limit * antes de ejecutar la consulta, y simplemente poner las cosas en el orden que desee. Así es como "insinúa" en la base de datos en esta área.

En general, desea usar EXPLAIN para confirmar el orden que está recibiendo, y que a veces se puede usar para confirmar visualmente que dos consultas están obteniendo el mismo plan.

Cuestiones relacionadas