Poniendo los JOIN en el orden correcto

1 comentario

Muchas veces cuando escribimos un SELECT que no es muy sencillo necesitamos relacionar a una tabla con otra u otras tablas. Eso lo hacemos con las cláusulas JOIN.

Como sabemos, hay dos clases de JOIN:

  • INNER JOIN
  • OUTER JOIN

La palabra INNER puede omitirse si se desea, ya que es la que por defecto asumirá el Firebird si no se escribe algo antes de la palabra JOIN. Los OUTER a su vez pueden ser: LEFT, RIGHT, FULL

Entonces, la pregunta es: ¿importa si se escribe primero un INNER o un OUTER? ¿O es lo mismo?

Consulta 1. Poniendo primero el INNER JOIN

SELECT
   *
FROM
   MiTabla1
JOIN
   MiTabla2
      ON MiCondición1
LEFT JOIN
   MiTabla3
      ON MiCondición2

Aquí se escribió primero el INNER JOIN (la palabra INNER no es obligatorio escribir) y luego el OUTER JOIN (la palabra OUTER tampoco es obligatorio escribir, al escribir LEFT ya el Firebird sabe que se trata de un OUTER)

Consulta 2. Poniendo primero el OUTER JOIN

SELECT
   *
FROM
   MiTabla1
LEFT JOIN
   MiTabla3
      ON MiCondición2
JOIN
   MiTabla2
      ON MiCondición1

Aquí se escribió primero el OUTER JOIN (en este caso, fue un LEFT) y luego el INNER JOIN (la palabra INNER es opcional, no se requiere escribirla)

¿Cuál consulta es mejor?

¿La Consulta 1 es más eficiente que la Consulta 2? ¿La Consulta 2 es más eficiente que la Consulta 1? ¿O son igual de eficientes?

El optimizador del Firebird solamente reordena las tablas en el PLAN hasta que encuentra el primer OUTER JOIN (sea LEFT, RIGHT, o FULL).

Por lo tanto, la correcta es la Consulta 1.

Conclusión:

El orden de los JOIN sí importa en Firebird porque el optimizador reordena las tablas para obtener un mejor PLAN solamente hasta que encuentra el primer OUTER JOIN.

¿Consejo?

Revisa todos tus SELECTs y todas tus vistas para asegurarte de que siempre los INNER JOIN se encuentren antes de los OUTER JOIN, conseguirás consultas más eficientes de esa manera.

Artículos relacionados:

INNER JOIN y OUTER JOIN

Ejemplo Nº 001 – Usando INNER JOIN

Ejemplo Nº 002 – Usando INNER JOIN eficientemente

Ejemplo Nº 003 – Escribiendo varios INNER JOIN

Ejemplo Nº 004 – Usando un INNER JOIN para autoreferenciar una tabla

Ejemplo Nº 006 – Usando LEFT JOIN e INNER JOIN

JOIN implícito y JOIN explícito

NATURAL JOIN y CROSS JOIN

Relacionando dos tablas: la forma vieja y la forma nueva

Teoría de Conjuntos: Unión, Intersección, Diferencia

Entendiendo las tablas autoreferenciadas

Autoreferenciar una tabla. Algunos ejemplos

El índice del blog Firebird21

El foro del blog Firebird21

Anuncios

Relacionando dos tablas: la forma vieja y la forma nueva

2 comentarios

En Firebird, cuando queremos relacionar dos tablas (o conjuntos de resultados) entre sí tenemos dos posibilidades:

  1. Usando la forma vieja
  2. Usando la forma nueva

Caso 1. Usando la forma vieja

Esta sintaxis fue establecida en el año 1989. Las tablas se listan separadas por comas después de la cláusula FROM y la condición que las relaciona se pone en la cláusula WHERE. No hay una sintaxis especial que distinga cuales de las condiciones del WHERE son para filtrar filas y cuales son para relacionar tablas, se supone que mirando la sentencia el desarrollador sabrá cual es cual.

¿Problemas?

  • La cláusula WHERE puede volverse muy larga y muy complicada de leer porque se la usa para relacionar tablas y también para filtrar filas
  • Solamente se pueden relacionar tablas que tengan valores idénticos, si una de las tablas tiene NULL en una columna no se podrá hacer la relación. En otras palabras: solamente se puede hacer un INNER JOIN, no se pueden hacer OUTER JOIN.

Sintaxis:

SELECT
   MiColumna1,
   MiColumna2
FROM
   MiTabla1,
   MiTabla2
WHERE
   MiCondición

Caso 2. Usando la forma nueva

Esta sintaxis fue establecida en el año 1992. La tabla principal se coloca después de la cláusula FROM y la tabla secundaria se coloca después de la cláusula JOIN, la condición que las relaciona se coloca después de ON. Por lo tanto se puede distinguir fácilmente cual es la condición usada para relacionar a la tablas y cual es la condición usada para filtrar filas, no hay confusión posible.

¿Ventajas?

  • Es muy fácil saber cual es la condición usada para relacionar a las dos tablas
  • Es muy fácil saber cual es la condición usada para filtrar filas
  • La cláusula WHERE es más corta y por lo tanto más fácil de leer que cuando se usa la forma vieja
  • Se puede usar tanto INNER JOIN como OUTER JOIN

Sintaxis:

SELECT
   MiColumna1,
   MiColumna2
FROM
   MiTabla1
JOIN
   MiTabla2
      ON MiCondición

Cuidado:

Tú puedes elegir cualquiera de las dos formas para relacionar tablas pero NUNCA debes mezclarlas. En un SELECT o usas la forma vieja o usas la forma nueva, no las mezcles, porque si las mezclas eso solamente te ocasionará problemas y ningún beneficio.

Recomendación:

La forma nueva es mejor, por eso se la inventó, por eso existe. Si ya tienes SELECTs escritos con la forma vieja y funcionan bien entonces déjalos como están, no los toques, pero para escribir todos tus nuevos SELECTs usa la forma nueva porque es la que verás cada vez más en todos los libros y documentos sobre SQL. Y es además la que siempre se usa en este blog.

Artículos relacionados:

Entendiendo a los JOIN

JOIN implícito y JOIN explícito

El índice del blog Firebird21