Django Q objects vs python code better performance?

What would provide better performance using filtering conditions with Q in django ORM or simply fetching unfiltered objects and comparing in python.

employee_qs = employee.objects.filter(state=States.ACTIVE, topic_assn__topic_id=instance.ss_topic_id).select_related('c_data').filter(
                Q(c_data__is_null=True) | Q(c_budget__gt=F('c_data__budget_spent') + offset_amt))

V/s


employee_qs = employee.objects.filter(state=States.ACTIVE, topic_assn__topic_id=instance.ss_topic_id).select_related('c_data')
for employee in employee_qs:
    if not employee.c_data or float(employee.budget)-employee.c_data.budget_spent > offset_amt:
        #do something...

Which of these two choices would be better performance wise?

>Solution :

TLDR: Q objects will be faster.

Why? Well filtering done with Q object will be done on the SQL server (either PostgreSQL, MariaDB). So two aspects should be considered:

  • with Q objects, unfiltered data will not be transferred from your database to your django server (less data over the network make things faster) ;
  • Q objects are converted to SQL WHERE clause, depending on how your table is configured (for instance, the presence of indexes on the columns that you are filtering) the SQL will use these indexes to filter data much faster than on the server side. Also, SQL servers are written in languages that are much faster than Python.

Leave a Reply