En SQL existen varias formas de realizar cálculos iterativos/recursivos:
WITH RECURSIVE) — son útiles para tareas como el recorrido de jerarquías (árboles, grafos, cadenas de referencias).Cuándo usar CTE recursivos:
Ejemplo:
WITH RECURSIVE tree AS ( SELECT id, parent_id, name, 1 AS level FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.parent_id, c.name, t.level + 1 FROM categories c JOIN tree t ON c.parent_id = t.id ) SELECT * FROM tree;
Si un CTE recursivo no resuelve la tarea o los datos son demasiado voluminosos, se aplican otros mecanismos (por ejemplo, procesamiento externo, tablas temporales o algoritmos especializados fuera de SQL).
¿Puede un CTE recursivo llevar a una ejecución infinita? ¿Cómo prevenirlo?
Respuesta:
Sí, si hay ciclos en el gráfico (por ejemplo, parent_id refiere de nuevo a un hijo), el CTE recursivo puede entrar en un bucle. La mayoría de sistemas de gestión de bases de datos soportan límites en el número máximo de niveles de recursión (MAXRECURSION para MS SQL o una opción similar). Es buena práctica siempre limitar la profundidad de la recursión.
-- MS SQL Server OPTION (MAXRECURSION 100)
Historia
En un proyecto financiero, se calculaba el saldo total a través de cadenas de cuentas relacionadas (padre-hijo) utilizando un CTE recursivo. Uno de los usuarios creó un ciclo en la estructura (un padre se convirtió en su propio hijo). La consulta comenzó a ejecutarse indefinidamente, sobrecargando el servidor. Se añadió una comprobación de ciclos y MAXRECURSION, y el problema se resolvió.
Historia
En un sistema de gestión de tareas, el estado de las tareas dependientes se calculaba con un procesamiento de curso. Después de migrar a un CTE recursivo, olvidaron prever índices óptimos por parent_id — el rendimiento cayó 5 veces, ya que en cada paso ocurrían operaciones de unión costosas.
Historia
La consulta para recorrer el árbol de categorías con un cursor funcionaba correctamente, pero tardaba 7 minutos en procesar 100,000 filas. Lo reescribieron en un CTE recursivo, considerado "lento", — obtuvieron el mismo resultado en 5 segundos gracias a la optimización del motor de trabajo con conjuntos.