ProgramaciónDesarrollador SQL / Desarrollador Backend

Describe diferentes formas de implementar cálculos iterativos complejos en SQL. ¿Cuándo deberías usar expresiones de tabla comunes recursivas (CTE) y cuándo es mejor recurrir a otros métodos?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

En SQL existen varias formas de realizar cálculos iterativos/recursivos:

  • CTE recursivos (WITH RECURSIVE) — son útiles para tareas como el recorrido de jerarquías (árboles, grafos, cadenas de referencias).
  • Cursore (CURSOR) — permiten procesar datos fila por fila, pero son menos eficientes para grandes volúmenes que las operaciones basadas en conjuntos.
  • Expresiones normales basadas en conjuntos — son preferibles en la mayoría de los casos (operan con conjuntos de filas sin iteraciones).

Cuándo usar CTE recursivos:

  • Para estructuras jerárquicas (categorías de productos, estructuras organizativas).
  • Para encontrar caminos/dimensiones de cadenas (por ejemplo, genealogía, gráficos de dependencia).

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).

Pregunta capciosa.

¿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)

Ejemplos de errores reales por desconocimiento de los matices del tema.


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.