En SQL hay dos formas de relacionar tablas entre sí:

  1. Con la cláusula FROM
  2. Con la cláusula JOIN

Cuando se las relaciona mediante la cláusula FROM se escribe algo como:

SELECT
   Columna1,
   Columna2,
   ColumnaN
FROM
   Tabla1,
   Tabla2
WHERE
   Condición_entre_Tabla1_y_Tabla2

En cambio, cuando se las relaciona mediante la cláusula JOIN se escribe algo como:

SELECT
   Columna1,
   Columna2,
   ColumnaN
FROM
   Tabla1
JOIN
   Tabla2
   ON Condición_entre_Tabla1_y_Tabla2

La primera forma (la que utiliza FROM) es la forma antigua de relacionar dos tablas entre sí. Está basada en el cálculo.

La segunda forma (la que utiliza JOIN) es la forma moderna de relacionar dos tablas entre sí. Está basada en el álgebra.

NOTA: Quizás no sabías que el lenguaje SQL está basado en tres ramas de la Matemática: el cálculo integral, el álgebra y la teoría de conjuntos.

Un JOIN es el producto cartesiano entre las dos tablas involucradas. Eso significa que el resultado de un JOIN combina cada fila de la primera tabla con cada fila de la segunda tabla.

Por ejemplo, si la primera tabla tiene 3 filas y la segunda tabla tiene 7 filas al hacer un JOIN el resultado tendrá 21 filas (que es lo que se obtiene al multiplicar 3 por 7)

En tablas compuestas por miles o por millones de filas, la cantidad de filas del resultado puede ser asombrosamente grande; por ese motivo es que siempre debemos acotar lo más posible a los JOIN. En otras palabras, ponerles la mayor cantidad de condiciones para que obtengamos un resultado manejable.

Ejemplo:

Nuestra tabla de SUCURSALES tiene estas filas:

JOIN1

Captura 1. Tabla de SUCURSALES (si haces clic en la captura la verás más grande)

Y nuestra tabla de BANCOS tiene estas filas:

JOIN2

Captura 2. Tabla de BANCOS (si haces clic en la captura la verás más grande)

Listado 1. Viendo el producto cartesiano de la tabla SUCURSALES por la tabla BANCOS

SELECT
   B.*,
   S.*
FROM
   BANCOS     B
JOIN
   SUCURSALES S
      ON B.BAN_IDENTI > 0

JOIN3

Captura 3. Resultado del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

 Como puedes ver, cada Banco se ha combinado con cada Sucursal. Eso ocurrió porque nuestra condición (B.BAN_IDENTI > 0) es siempre verdadera e involucra a solamente una de las tablas. Podemos también ver la cantidad de lecturas ocurridas en cada tabla haciendo clic en la pestaña «Performance Analysis» del EMS SQL Manager y esto será lo que obtendremos:

JOIN4

Captura 4. Performance Analysis del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

 Acotemos ahora el JOIN para volverlo más manejable.

Listado 2. Viendo el producto cartesiano de la tabla SUCURSALES por la tabla BANCOS relacionando ambas tablas.

SELECT
   B.*,
   S.*
FROM
   BANCOS     B
JOIN
   SUCURSALES S
   ON B.BAN_CODSUC = S.SUC_CODIGO

Como ahora tenemos una condición que relaciona a ambas tablas entre sí (mediante las columnas B.BAN_CODSUC y S.SUC_CODIGO) aunque el resultado sigue siendo el producto cartesiano entre ellas (es decir: todas las filas de SUCURSALES combinadas con todas las filas de BANCOS) la condición limita o acota las filas devueltas por el SELECT, quedando ahora así:

JOIN5

Captura 5. Relacionando las tablas BANCOS y SUCURSALES entre sí (si haces clic en la captura la verás más grande)

Y al hacer clic sobre «Performance Analysis» esto es lo que obtenemos:

JOIN6

Captura 6. Performance Analysis del JOIN entre BANCOS y SUCURSALES (si haces clic en la captura la verás más grande)

Si ahora le ponemos una condición usando la cláusula WHERE el conjunto resultado estará aún más limitado o acotado.

Listado 3. Un JOIN con una cláusula WHERE

SELECT
   B.*,
   S.*
FROM
   BANCOS B
JOIN
   SUCURSALES S
   ON B.BAN_CODSUC = S.SUC_CODIGO
WHERE
   B.BAN_IDENTI = 6

Al usar WHERE para poner una condición que limita la cantidad de filas devueltas obtendremos aún menos filas, como podemos ver aquí:

JOIN7

Captura 7. Usando WHERE para limitar las filas devueltas (si haces clic en la captura la verás más grande)

Y al hacer clic sobre la pestaña «Performance Analysis» esto es lo que obtenemos:

JOIN8 

Captura 8. Performance Analysis al usar WHERE para limitar las filas devueltas (si haces clic en la captura la verás más grande)

Conclusión:

Un JOIN es igual al producto cartesiano entre las filas de dos tablas. Eso significa que se combinan todas las filas de la primera tabla con todas las filas de la segunda tabla. Debido a ello en tablas que tienen miles o millones de filas el resultado de un JOIN puede estar compuesto por una cantidad asombrosamente grande de filas. Para limitar esa cantidad debemos asegurarnos que una o más columnas de la primera tabla se relacionen con una o más columnas de la segunda tabla. Además, siempre que podamos debemos usar la cláusula WHERE para limitar aún más la cantidad de filas devueltas.

En nuestro ejemplo, con el SELECT del Listado 1. el Firebird hizo 24 lecturas (21 en BANCOS y 3 en SUCURSALES). Con el SELECT del Listado 2. el Firebird hizo 14 lecturas (7 en BANCOS y 7 en SUCURSALES). Con el SELECT del Listado 3. el Firebird hizo 4 lecturas (1 en BANCOS y 3 en SUCURSALES). Al ir poniendo condiciones conseguimos bajar la cantidad inicial de lecturas (24) a solamente 4.

Menos lecturas implica mucha mayor velocidad de respuesta.

Artículo relacionado:

El índice del blog Firebird21