Optimización de Filtrado y Listado con Symfony

Clase 19 de 22Curso de Bases de Datos en Symfony

Contenido del curso

Datos iniciales

Resumen

Cuando trabajamos con Symfony y Doctrine, cada consulta innecesaria a la base de datos representa un costo en rendimiento. Mover la lógica de consultas desde las vistas hacia los controladores, utilizando métodos personalizados en los repositorios, es una de las estrategias más efectivas para optimizar una aplicación. A continuación se desglosa cómo lograrlo con el filtrado por etiquetas y el listado de comentarios.

¿Cómo crear un método personalizado para filtrar productos por etiqueta?

El primer paso consiste en modificar el repositorio de productos para agregar un método que filtre específicamente por etiqueta [01:06]. En lugar de dejar que la vista resuelva qué productos pertenecen a una etiqueta, delegamos esa responsabilidad a un método aislado dentro del repositorio.

El proceso es el siguiente:

  • Se copia la estructura de un método existente en el repositorio y se personaliza.
  • El nuevo método, que puede llamarse buscarPorEtiquetas, recibe como parámetro una etiqueta y retorna un array [02:15].
  • Dentro del método se utiliza createQueryBuilder para armar la consulta y se configura un parámetro con setParameter, asociando la variable tag al valor recibido [02:48].
  • Se agrega una condición con product.tags para establecer la relación entre productos y la etiqueta consultada [03:18].

Este enfoque sigue la misma lógica que Symfony muestra en sus ejemplos de repositorios: definir parámetros, construir la consulta y retornar los resultados.

¿Por qué la vista debe dejar de consultar productos?

Un detalle importante aparece al verificar el resultado. Aunque el método ya está funcionando, el profiler de Symfony puede mostrar tres consultas en lugar de dos [03:30]. Esto ocurre porque la plantilla Twig sigue intentando obtener los productos de la etiqueta por su cuenta.

La solución es ir a la plantilla en plantillas/páginas/etiquetas y eliminar la línea que consulta los productos de la etiqueta desde la vista [03:45]. Al hacerlo, el resultado correcto es:

  • Una consulta para obtener la etiqueta.
  • Una consulta para obtener los productos filtrados.

Dos consultas en total, lo cual representa una mejora significativa.

¿Cómo optimizar el listado de comentarios con left join?

El siguiente objetivo es el repositorio de comentarios [04:08]. Aquí se necesita un método personalizado que obtenga todos los comentarios junto con la información de sus productos relacionados, todo en una sola consulta.

Los pasos para construirlo son:

  • Crear un nuevo método en el repositorio de comentarios que retorne un array [04:30].
  • Utilizar createQueryBuilder con un alias descriptivo, por ejemplo comentarios.
  • Agregar un select que haga referencia a la relación con productos, ya que un comentario pertenece a un producto [04:48].
  • Aplicar leftJoin sobre comentario.producto para traer la información del producto en la misma consulta [05:00].
  • Ordenar de manera descendente a partir del ID del comentario con orderBy [05:10].
  • Finalizar con getQuery y getResult para obtener los datos.

Al actualizar la página, el profiler confirma que toda la información se obtiene en una única consulta [05:25]. Los tiempos de respuesta mejoran notablemente cuando se consolidan las consultas de esta manera.

¿Cuál es el principio detrás de esta optimización?

La idea central es que las consultas se ejecuten en el controlador y no en la vista [05:35]. El controlador invoca un método aislado del repositorio donde reside toda la lógica de acceso a datos. La vista simplemente recibe y muestra la información ya procesada.

El resultado esperado tras aplicar estas modificaciones es:

  • En la sección de comentarios: una sola consulta.
  • En el home: una sola consulta.
  • En las etiquetas: dos consultas.

Cada método personalizado en el repositorio actúa como una pieza reutilizable y clara, separando responsabilidades y evitando el problema conocido como N+1 queries, donde cada elemento en una lista genera una consulta adicional.

Si ya implementaste estos cambios, comparte cómo impactaron los números en tu profiler y qué otras optimizaciones consideras aplicar en tus repositorios.