objects.filter(id=customer_id).first() vs objects.get(id=customer_id)

Is there any difference between the following in terms of query execution speed ?

cust_data = Customer.objects.filter(id=customer_id).first()

vs

cust_data = Customer.objects.get(id=customer_id)

There may be because the first one executes the query with LIMIT 1 and the second with LIMIT 21 (it could have been done with a LIMIT 2, but using 21 is what I see in Django source code).

However, those two statements do not achieve the same goal. The first one always returns (None if no record matches the query, the first matching record otherwise) and the second one raises exceptions if not one and only one record matches the query.

With the first statement, we cannot identify if several records would have match the query (you have to attempt returning at least 2 objects to make sure there is only one corresponding in database).

My explanation above is for the general case, because if you are filtering on fields that correspond to a unique constraint, the constraint ensures that it will return at most 1 result.

So, yes, there probably is a penalty on using .get() over .first() (that I think could be improved by limiting the returned results to 2 instead of 21 in the underlying query) but the first one can only be substituted to the second one only in particular circumstancies (filtering on unique constraint)

1 Like

Unfortunately, the previous answer is not accurate.

Since the LIMIT clause is being handled by PostgreSQL within the database, it doesn’t matter whether the limit is set to 2, 21, or 1000000. The limit clause is applied after the result set is identified, and if the result set is smaller than the limit, it doesn’t matter.

Changing the LIMIT 21 to LIMIT 2 is only going to matter in those cases where get ends up returning more than 1 row, which should not happen when you’re testing the pk of a model.

So to address your direct question of:

The answer is no - for this specific situation where it’s an indexed field returning 1 result. (See note below)

The prior answer is accurate regarding the effective difference between the two - where the first() version will return None if the pk is not found and get throws an error. Then it becomes an application issue as to how to handle that situation should it occur, and how you handle could have more significant effects on your application than any theoretical effect of the query.

Note: The other abnormal case would be those situations where the query is returning more than one row. Since first() applies a sort to the queryset being returned, that would add some nominal processing within the database to the resultset being generated before returning the first element of that set.

1 Like