Todos los productos
Search
Centro de documentos

Realtime Compute for Apache Flink:Join regular

Última actualización: Sep 03, 2026

Flink SQL admite joins regulares (también conocidos como joins de doble flujo) sobre tablas dinámicas. A diferencia de los joins por lotes, los resultados se actualizan continuamente conforme llegan nuevos datos a cualquiera de los flujos, lo que garantiza que la salida final sea coherente con la que produciría un join por lotes sobre los mismos datos.

Contexto

Los joins regulares almacenan en búfer todos los registros históricos de ambos flujos de entrada dentro del estado de Flink, de modo que cualquier fila entrante pueda compararse con todas las filas vistas previamente en el otro flujo. Esto implica que el estado crece de forma indefinida mientras el trabajo se mantenga en ejecución. En trabajos de larga duración con flujos de alto volumen, este crecimiento ilimitado del estado puede agotar la memoria y provocar fallos.

Para limitar el tamaño del estado, establezca un tiempo de vida (TTL) del estado mediante el parámetro table.exec.state.ttl o la sugerencia JOIN_STATE_TTL específica por flujo (consulte Hints). Tenga en cuenta que la eliminación de registros del estado puede afectar la precisión de los resultados: las filas que hayan expirado ya no coincidirán con los datos nuevos.

Si el crecimiento ilimitado del estado representa un problema, considere también como alternativas los joins de intervalo, los joins de búsqueda y los joins de ventana.

Sintaxis

tableReference [, tableReference ]*
| tableExpression [ NATURAL | INNER ] [ { LEFT | RIGHT | FULL } [ OUTER ] ] JOIN tableExpression [ joinCondition ]
| tableExpression CROSS JOIN tableExpression
| tableExpression [ CROSS | OUTER ] APPLY tableExpression

joinCondition:
    ON booleanExpression
  | USING '(' column [, column ]* ')'
  • tableReference: el nombre de la tabla.

  • tableExpression: la expresión de tabla.

  • joinCondition: la condición de unión.

Coloque primero la tabla con menor frecuencia de actualización y al final la que tenga mayor frecuencia. Esta práctica reduce la cantidad de estado que debe evaluarse por cada fila entrante.

Tipos de join

INNER JOIN

Devuelve únicamente las filas where la condición de unión se cumple en ambos lados.

SELECT id, productName, status
FROM orders o
JOIN shipments s
  ON o.id = s.orderId;

LEFT JOIN

Devuelve todas las filas de la tabla izquierda. Las filas sin coincidencia en el lado derecho generan valores NULL en las columnas correspondientes a la derecha.

SELECT o.id, o.productName, s.status
FROM orders o
LEFT JOIN shipments s
  ON o.id = s.orderId;

RIGHT JOIN

Devuelve todas las filas de la tabla derecha. Las filas sin coincidencia en el lado izquierdo generan valores NULL en las columnas correspondientes a la izquierda.

SELECT o.id, o.productName, s.status
FROM orders o
RIGHT JOIN shipments s
  ON o.id = s.orderId;

FULL OUTER JOIN

Devuelve todas las filas de ambas tablas. Las filas sin coincidencia en ninguno de los lados generan valores NULL en las columnas sin correspondencia.

SELECT o.id, o.productName, s.status
FROM orders o
FULL OUTER JOIN shipments s
  ON o.id = s.orderId;

CROSS JOIN

Devuelve el producto cartesiano de ambas tablas; cada fila del lado izquierdo se combina con cada fila del lado derecho.

SELECT *
FROM orders o
CROSS JOIN shipments s;

Sugerencias

En Ververica Runtime (VVR) 8.0.1 y versiones posteriores, utilice hints para especificar distintos valores de tiempo de vida (TTL) para los estados de los flujos izquierdo y derecho. Esto reduce la cantidad de datos de estado que deben mantenerse.

Importante

La sugerencia JOIN_STATE_TTL aplica exclusivamente a joins regulares. No es compatible con joins de búsqueda, de intervalo ni de ventana. Las sugerencias para joins regulares son experimentales y su sintaxis podría cambiar en futuras versiones.

Sintaxis

-- VVR 8.0.1 and later
SELECT /*+ JOIN_STATE_TTL('tableReference1' = 'ttl1' [, 'tableReference2' = 'ttl2']*) */ ...

-- VVR 8.0.7 and later also support the Apache Flink syntax
SELECT /*+ STATE_TTL('tableReference1' = 'ttl1' [, 'tableReference2' = 'ttl2']*) */ ...

Establezca tableReference como un nombre de tabla, un nombre de vista o un alias. Si define un alias para una tabla, utilícelo también en la sugerencia.

Si especifica un TTL solo para uno de los flujos, el otro utilizará el TTL del despliegue definido por el parámetro table.exec.state.ttl. El valor predeterminado es de 1.5 días. Para más detalles, consulte Basic configurations.

Ejemplos

Todos los ejemplos utilizan JOIN_STATE_TTL para definir tiempos de vida independientes para cada flujo. VVR 8.0.7 y versiones posteriores también aceptan la sintaxis equivalente STATE_TTL que se muestra en los comentarios.

Uso de un alias

SELECT /*+ JOIN_STATE_TTL('o' = '3d', 'p' = '1d') */
  o.rowtime, o.productid, o.orderid, o.units, p.name, p.unitprice
FROM Orders AS o
JOIN Products AS p
  ON o.productid = p.productid;

-- VVR 8.0.7 and later
SELECT /*+ STATE_TTL('o' = '3d', 'p' = '1d') */
  o.rowtime, o.productid, o.orderid, o.units, p.name, p.unitprice
FROM Orders AS o
JOIN Products AS p
  ON o.productid = p.productid;

Uso de un nombre de tabla

SELECT /*+ JOIN_STATE_TTL('Orders' = '3d', 'Products' = '1d') */ *
FROM Orders
JOIN Products
  ON Orders.productid = Products.productid;

-- VVR 8.0.7 and later
SELECT /*+ STATE_TTL('Orders' = '3d', 'Products' = '1d') */ *
FROM Orders
JOIN Products
  ON Orders.productid = Products.productid;

Uso de un nombre de vista

CREATE TEMPORARY VIEW v AS
SELECT id, ...
FROM (
  SELECT id, ROW_NUMBER() OVER (PARTITION BY ... ORDER BY ..) AS rn
  FROM src1
  WHERE ...
) tmp
WHERE rn = 1;

SELECT /*+ JOIN_STATE_TTL('v' = '1d', 'b' = '3d') */ v.* , b.*
FROM v
LEFT JOIN src2 AS b ON v.id = b.id;

-- VVR 8.0.7 and later
SELECT /*+ STATE_TTL('v' = '1d', 'b' = '3d') */ v.* , b.*
FROM v
LEFT JOIN src2 AS b ON v.id = b.id;

Ejemplos

Ejemplo 1: Unión de las tablas Orders y Shipments

Datos de prueba

Tabla 1. Orders

id

productName

ordertime

1

phone_a

2025-05-01 10:00:00.0

2

notebook_x

2025-05-01 10:02:00.0

3

phone_b

2025-05-01 10:03:00.0

4

pad_m

2025-05-01 10:05:00.0

Tabla 2. Shipments

shipId

orderId

status

shipTime

101

1

shipped

2025-05-01 11:00:00.0

102

2

delivered

2025-05-01 17:00:00.0

103

3

shipped

2025-05-01 12:00:00.0

104

4

shipped

2025-05-01 11:30:00.0

Instrucción de prueba

SELECT id, productName, status
FROM orders o
JOIN shipments s
  ON o.id = s.orderId;

Resultados de la prueba

id

productName

status

1

phone_a

shipped

2

notebook_x

delivered

3

phone_b

shipped

4

pad_m

shipped

Ejemplo 2: Unión de las tablas datahub_stream1 y datahub_stream2

Datos de prueba

Tabla 3. datahub_stream1

a (BIGINT)

b (BIGINT)

c (VARCHAR)

0

10

test11

1

10

test21

Tabla 4. datahub_stream2

a (BIGINT)

b (BIGINT)

c (VARCHAR)

0

10

test11

1

10

test21

0

10

test31

1

10

test41

Instrucción de prueba

SELECT s1.c, s2.c
FROM datahub_stream1 AS s1
JOIN datahub_stream2 AS s2
  ON s1.a = s2.a
WHERE s1.a = 0;

Resultados de la prueba

s1.c (VARCHAR)

s2.c (VARCHAR)

test11

test11

test11

test31