Optimiza las Consultas a Base de Datos en Django

Optimiza las Consultas a Base de Datos en Django

Hoy les voy a mostrar como optimizar las consultas a base de datos de su sitio web desarrollado sobre Django 👌

Django es un framework muy sencillo y poderoso, y su ORM tiene una capa de abstracción tan fuerte que es normal meter la pata y tener pedazos de código que no son muy performantes. Esa misma abstracción es la que nos puede jugar en contra si no somos conscientes de las operaciones que estamos ejecutando contra la base de datos, y la cosa se puede poner peor si encima no tenemos muy presente como trabajan las QuerySets de Django. Lo bueno es que tenemos herramientas que nos hacen muy fácil la tarea de debuggear nuestro código para encontrar los bottleneck que bajan la performance, y en base a este análisis hallar otro camino por el cual llegar al mismo resultado con mejores tiempos de respuesta.

Tal como se explica en el articulo Database access optimization de la documentación de Django, lo primero y fundamental es hacer profiling de la base de datos. El profiling es básicamente el análisis del rendimiento de la aplicación mediante la información reunida en tiempo de ejecución. Que quiere decir esto?: que se realiza un análisis de cada una de las queries que ejecuta la base de datos para determinar el tiempo, memoria y otros recursos que demanda en completarse cada operación.
Esta debería ser una práctica de programación obligatoria ya que nos permite determinar que queries son mas costosas para nuestra aplicación.

Entre las distintas herramientas de profiling que podemos encontrar, Django Debug Toolbar es una de las más completas y usadas. Se trata de un set de paneles que nos mostrara distinta información para hacer mucho mas sencilla la tarea de profiling y debugging de nuestro sitio web.

Instalando y configurando django-debug-toolbar

Como con cualquier otro paquete de Python, Django Debug Toolbar es muy sencillo de instalar con pip:

$ pip install django-debug-toolbar



Y su configuración no es tanto mas complicada. En primer lugar debemos asegurarnos de agregar 'debug_toolbar' a las INSTALLED_APPS, y ademas tener seteado correctamente los staticfiles.


settings.py

INSTALLED_APPS = [  
    # ...
    'django.contrib.staticfiles',
    # ...
    'debug_toolbar',
]

STATIC_URL = '/static/'  



Casi toda la funcionalidad de Debug Toolbar esta incluida dentro de un middleware, asi que es fundamental habilitarlo:

MIDDLEWARE = [  
    # ...
    'debug_toolbar.middleware.DebugToolbarMiddleware',
    # ...
]



En Django el orden de los middlewares es relevante, por lo que deben asegurarse de incluir DebugToolbarMiddleware lo mas arriba posible, pero posterior a cualquier otro middleware que se encargue de encodear el response, como podría ser GZipMiddleware.

Por ultimo vamos a agregar un setting que Debug Toolbar usa para determinar si debe mostrarse o no y le vamos a asignar la IP 127.0.0.1. Con esta configuración la barra se mostrara solo si estamos desarrollando en local:

INTERNAL_IPS = '127.0.0.1'  


Por ultimo agregamos las URL:


urls.py

import debug_toolbar

urlpatterns = [  
        # ...
        url(r'^__debug__/', include(debug_toolbar.urls)),
        # ...
]


Esta es la configuración básica para tener la toolbar funcionando, y en los paneles que vienen por defecto ya tendremos prácticamente todo lo que necesitamos 😉

Paneles

Como comentaba anteriormente, Debug Toolbar consta de un set de paneles que nos brindan distinta información relevante para debuggear nuestra aplicación o sito web:

  • Version: Muestra la versión de Python, Django y cualquier otra app instalada si fuera posible.
  • Timer: Nos muestra el tiempo que se demora cada request.
  • Settings: Las configuraciones de setting.py
  • Headers: Este panel muestra las peticiones y respuestas HTTP
  • Request: Información de la vista, cookies, sesion, GET y POST.
  • SQL: Nos muestra las queries SQL con su tiempo de ejecución e información relacionada.
  • Template: Vemos las plantillas renderizadas y su contexto.
  • Static files: Los archivos estáticos usados y su ubicación.
  • Cache: Podemos visualizar las llamadas a cache.
  • Signal: Una lista de los Signals, sus args y receivers.
  • Redirects: Ante una dirección la toolbar mostrara una pagina intermedia antes de redirigir para visualizar cualquier información de debug.

Como ven, Debug Toolbar nos muestra muchísima información, pero de todos los paneles el que más nos interesa para este post es el panel SQL:

Django Debug Toolbar panels

Este panel nos muestra cada una de las queries con su tiempo de ejecución (en milisegundos) y un timeline que nos permite visualizar de una forma mucho mas gráfica cuales son las que mas tiempo demandan a nuestra aplicación. Si expandimos el botón [+] ubicado a la izquierda de cada query podemos ver que linea de nuestro código la ejecuta.

Panel SQL

El botón SEL nos dirige a una nueva página que contiene la sentencia SQL completa, el tiempo que demanda su ejecución, la base de datos y los datos devueltos por la query.

Sentencia SQL y datos devueltos por el botón Sel

La accion EXPL en cambio, nos muestra a un análisis mas profundo y técnico de la query, donde se explican los distintos pasos de la ejecución.

Explicación de la sentencia SQL devuelta por el botón Expl

Con toda esta información a su disposición ya pueden empezar a analizar su sitio web y optimizar los accesos a la base de datos. Tengan en cuenta siempre que la velocidad de carga y repuesta de un sitio web es tan importante hoy en día que Google penaliza en sus resultados de búsqueda a las web con tiempos de carga altos, y uno de los principales factores que influyen en el buen desempeño de un sitio web son las consultas a la base de datos.

Para finalizar, no dejen de entender como funcionan las QuerySets de Django, ya que es vital para obtener un buen rendimiento con código sumamente simple.

Como se evaluan las QuerySets en Django

Para evitar problemas de performance es importante que entiendan los siguientes conceptos:

  • Las QuerySets se ejecutan en diferido. Esto quiere decir la acción de crear un QuerySet no involucra ninguna actividad con la base de datos, sino hasta el momento de ser evaluada.

  • Cuando se evalua un QuerySet. Un Queryset ejecuta su consulta a la base de datos cuando lo iteramos, aplicamos un slice ([0:5]), lo pasamos a un list(), entre otros.

  • Como se guardan los datos en memoria. Cada QuerySet contiene un caché para minimizar el acceso a la base de datos, y aprender a usarlo nos permitirá escribir código mas eficiente.

Espero que este post te sirva y ayude a mejorar tus desarrollos. Si tienen alguna duda déjenla en los comentarios o escríbanme por mis redes sociales. Me interesa mucho escucharlos ❤.




Post picture by Emily Morter

comments powered by Disqus