Algoritmos de procesamiento
MySQL puede procesar una vista con tres algoritmos diferentes: MERGE, TEMPTABLE y UNDEFINED. El algoritmo determina si MySQL integra la consulta de la vista con la consulta exterior o si primero materializa la vista en una tabla temporal. Esto tiene un impacto directo en el rendimiento y en si la vista es actualizable.
Los tres algoritmos
| Algoritmo | Descripción | Actualizable |
|---|---|---|
| MERGE | MySQL fusiona la consulta de la vista con la consulta externa | Sí |
| TEMPTABLE | MySQL ejecuta la vista primero y almacena el resultado en una tabla temporal | No |
| UNDEFINED | MySQL elige automáticamente entre MERGE y TEMPTABLE | Depende |
Sintaxis
CREATE ALGORITHM = MERGE VIEW nombre AS SELECT ...;
CREATE ALGORITHM = TEMPTABLE VIEW nombre AS SELECT ...;
CREATE ALGORITHM = UNDEFINED VIEW nombre AS SELECT ...; -- Por defectoMERGE
Con MERGE, MySQL combina la consulta de la vista con la consulta que la usa, creando una sola consulta optimizada:
CREATE ALGORITHM = MERGE VIEW v_productos_caros AS
SELECT id, nombre, precio, stock
FROM productos
WHERE precio > 500;
-- Cuando ejecutas:
SELECT * FROM v_productos_caros WHERE stock > 20;
-- MySQL lo transforma internamente en:
-- SELECT id, nombre, precio, stock FROM productos WHERE precio > 500 AND stock > 20;| id | nombre | precio | stock |
|---|---|---|---|
| 1 | iPhone 15 Pro | 1299.99 | 45 |
| 2 | Samsung Galaxy S24 | 899.99 | 62 |
| 3 | Google Pixel 8 | 699.00 | 38 |
| 4 | Xiaomi 14 | 599.99 | 80 |
| 5 | MacBook Air M3 | 1399.00 | 25 |
MERGE es el algoritmo más eficiente porque permite al optimizador trabajar con la consulta completa y usar índices de las tablas subyacentes.
TEMPTABLE
Con TEMPTABLE, MySQL ejecuta la consulta de la vista primero, almacena los resultados en una tabla temporal, y luego ejecuta la consulta exterior sobre esa tabla temporal:
CREATE ALGORITHM = TEMPTABLE VIEW v_stats_productos AS
SELECT
categoria_id,
COUNT(*) AS total,
AVG(precio) AS precio_medio,
MAX(precio) AS precio_max
FROM productos
GROUP BY categoria_id;
SELECT * FROM v_stats_productos WHERE total > 3;| categoria_id | total | precio_medio | precio_max |
|---|---|---|---|
| 6 | 4 | 849.74 | 1299.99 |
MySQL no puede usar MERGE aquí porque la vista tiene GROUP BY y funciones de agregación. La tabla temporal no tiene índices, así que filtrar sobre ella puede ser lento con muchos datos. Para mejorar el rendimiento en esos casos, considera añadir índices a las tablas subyacentes.
UNDEFINED
UNDEFINED es el algoritmo por defecto. MySQL elige automáticamente entre MERGE y TEMPTABLE:
-- MySQL elige MERGE para vistas simples
CREATE VIEW v_simple AS
SELECT nombre, precio FROM productos WHERE activo = TRUE;
-- MySQL elige TEMPTABLE para vistas con agregación
CREATE VIEW v_agregada AS
SELECT categoria_id, COUNT(*) AS total FROM productos GROUP BY categoria_id;MySQL prefiere MERGE siempre que sea posible porque es más eficiente.
Cuándo MySQL usa TEMPTABLE
MySQL se ve forzado a usar TEMPTABLE cuando la vista contiene:
- Funciones de agregación: COUNT, SUM, AVG, MIN, MAX
- DISTINCT
- GROUP BY
- HAVING
- UNION o UNION ALL
- Subconsultas en la lista SELECT
-- Ver qué algoritmo usa una vista
SELECT TABLE_NAME, VIEW_DEFINITION, IS_UPDATABLE
FROM information_schema.VIEWS
WHERE TABLE_SCHEMA = 'tienda_mysql';Impacto en rendimiento
-- MERGE: MySQL puede usar el índice de categoria_id
EXPLAIN SELECT * FROM v_productos_caros WHERE stock > 20;| id | select_type | table | type | possible_keys | key | rows | Extra |
|---|---|---|---|---|---|---|---|
| 1 | SIMPLE | productos | ALL | NULL | NULL | 30 | Using where |
-- TEMPTABLE: MySQL crea tabla temporal sin índices
EXPLAIN SELECT * FROM v_stats_productos WHERE total > 3;| id | select_type | table | type | possible_keys | key | rows | Extra |
|---|---|---|---|---|---|---|---|
| 1 | PRIMARY | derived2 | ALL | NULL | NULL | 11 | Using where |
| 2 | DERIVED | productos | ALL | NULL | NULL | 30 | Using temporary |
La vista TEMPTABLE aparece como derived en el EXPLAIN, indicando que se materializa como tabla temporal.
Recomendaciones
- Usa
ALGORITHM = UNDEFINEDy deja que MySQL elija - Evita
TEMPTABLEexplícito a menos que necesites garantizar que la vista no sea actualizable - Para vistas de rendimiento crítico, prefiere diseños que permitan
MERGE - Las vistas con JOIN simples generalmente usan
MERGE - Si necesitas agregar datos, considera si una tabla resumen es mejor que una vista
Limpieza
DROP VIEW IF EXISTS v_productos_caros;
DROP VIEW IF EXISTS v_stats_productos;
DROP VIEW IF EXISTS v_simple;
DROP VIEW IF EXISTS v_agregada;En el siguiente artículo veremos WITH CHECK OPTION, que previene modificaciones que harían desaparecer filas de la vista.
Escrito por Eduardo Lázaro
