¿Qué es la arquitectura MPP de Teradata? (explicado simple)
Si venís de motores como PostgreSQL o MySQL, Teradata puede parecer distinto desde el primer día: no es solo "otra base de datos SQL", es un sistema pensado desde cero para repartir el trabajo entre muchas unidades de proceso al mismo tiempo. Esa idea se llama MPP (Massively Parallel Processing, procesamiento masivamente paralelo) y es la razón por la que Teradata puede escanear y agregar miles de millones de filas en segundos.
Shared-nothing: cada AMP tiene lo suyo
La pieza central de la arquitectura es el AMP (Access Module Processor). Un AMP es una unidad de proceso virtual que posee su propia porción de datos, su propio disco y su propia porción de CPU. Un sistema Teradata típico tiene decenas o cientos de AMPs corriendo en paralelo dentro del mismo clúster.
Esto es lo que se conoce como arquitectura shared-nothing: a diferencia de un motor monolítico (como PostgreSQL en una sola instancia) donde todo el trabajo pasa por el mismo CPU y el mismo disco, en Teradata cada AMP resuelve su parte del trabajo de forma independiente, sin pelear por los mismos recursos que los demás AMPs. El resultado: si tenés 100 AMPs, en teoría podés escanear una tabla 100 veces más rápido que con un solo proceso, porque cada AMP lee solo su porción de los datos.
El Parsing Engine (PE) y el BYNET
Cuando enviás una consulta SQL, no le hablás directamente a los AMPs. Le hablás al PE (Parsing Engine), que es el componente que recibe el SQL, lo parsea, genera un plan de ejecución y lo distribuye a los AMPs involucrados. El PE también recolecta los resultados parciales de cada AMP y los devuelve como una única respuesta al cliente.
La comunicación entre PEs y AMPs viaja por el BYNET, una red de interconexión interna de alta velocidad diseñada específicamente para mover datos entre los nodos del sistema sin convertirse en cuello de botella. Cuando una consulta necesita "redistribuir" filas entre AMPs (por ejemplo, para un join donde las tablas no comparten Primary Index), es el BYNET el que transporta esos datos.
El Primary Index: quién decide en qué AMP vive cada fila
Acá está la pieza que más sorprende a quien viene de otros motores: en Teradata, cada tabla tiene un Primary Index (PI), una o varias columnas que determinan a qué AMP pertenece cada fila. No es lo mismo que una clave primaria de PostgreSQL o MySQL (que solo garantiza unicidad); el PI de Teradata es, ante todo, una decisión de distribución física.
Cuando insertás una fila, el PE calcula un valor de hash sobre las columnas del Primary Index. Ese hash determina, de forma determinística, a qué AMP va la fila. Todas las filas con el mismo valor de PI terminan siempre en el mismo AMP.
-- Ejemplo: definir el Primary Index al crear una tabla
CREATE TABLE orders (
order_id INTEGER,
customer_id INTEGER,
order_date DATE,
status VARCHAR(20)
)
PRIMARY INDEX (customer_id);
Con este ejemplo, todos los pedidos de un mismo customer_id quedan en el mismo AMP. Eso tiene dos consecuencias importantes:
- Reparto de trabajo (skew): si el PI está mal elegido —por ejemplo, una columna con muy poca variedad de valores, como
status, que puede tener solo 3 o 4 valores posibles—, unos pocos AMPs terminan con muchísimas más filas que el resto. Eso genera skew (desbalanceo): mientras la mayoría de los AMPs terminan su trabajo enseguida, uno o dos quedan sobrecargados y frenan a toda la consulta, porque el sistema espera al AMP más lento. - Joins locales: si dos tablas que se unen frecuentemente comparten el mismo Primary Index (por ejemplo,
ordersyorder_items, ambas con PI encustomer_iduorder_idsegún el caso), el join puede resolverse dentro de cada AMP, sin mover una sola fila por el BYNET. Esto se llama join local y es uno de los mayores factores de rendimiento en Teradata.
Cómo se reparten las filas entre AMPs: un ejemplo
Imaginá una tabla de clientes con Primary Index en customer_id y un clúster con 4 AMPs. Cada customer_id pasa por la función de hash, y ese hash "cae" siempre en el mismo AMP:
customer_id = 101 --> hash(101) --> AMP 2
customer_id = 102 --> hash(102) --> AMP 4
customer_id = 103 --> hash(103) --> AMP 1
customer_id = 104 --> hash(104) --> AMP 2
customer_id = 105 --> hash(105) --> AMP 3
Notá que customer_id = 101 y customer_id = 104 cayeron en el mismo AMP (AMP 2): eso es normal, el hash no garantiza "un cliente por AMP" sino una distribución estadísticamente pareja cuando hay muchos valores distintos. Con miles o millones de clientes, cada AMP termina con una porción de tamaño similar, y una consulta como SELECT COUNT(*) FROM customers se resuelve en paralelo: cada AMP cuenta su porción al mismo tiempo, y el PE solo suma los 4 resultados parciales.
Por qué esto importa para vos como analista o desarrollador SQL
No necesitás administrar el clúster para que esto te importe. Entender el modelo MPP cambia cómo escribís consultas:
- Elegir bien el Primary Index de una tabla (o entender el que ya existe) explica por qué algunos joins son rapidísimos y otros redistribuyen datos entre AMPs.
- Un
GROUP BYo unCOUNT(*)sobre una tabla enorme es rápido precisamente porque cada AMP procesa su porción en paralelo. - Ver un plan con
EXPLAINy encontrar la palabra "redistribute" te dice que el optimizador tuvo que mover filas por el BYNET porque los PI no coincidían: una pista para revisar el diseño.
Este es exactamente el punto de partida del dojo: el Nivel 0 del curso explica la arquitectura MPP paso a paso, con las mismas ideas de AMP, PE y Primary Index que acabás de leer, antes de pasar a escribir las primeras consultas.
Próximo paso
Si te interesa ver cómo esta arquitectura MPP se compara con motores más tradicionales, seguí con Teradata vs PostgreSQL y MySQL: diferencias clave. Y si ya querés ensuciarte las manos con SQL real de Teradata, probá la demo interactiva del dojo.
¿Querés practicar esto con ejercicios reales? Desbloqueá los 9 niveles del dojo por 5 USD.