Django ORM creates indices for primary and foreign keys out of the box. However, if you perform a lot of queries on the rest of the columns (the columns that are used in a
filter() method) it makes sense to add indexes to them. This can be accomplished by adding
unique=True argument to a model field.
If you do a lot of cross-table queries (loading data from multiple tables) you might end up with N+1 problem. N+1 problem is when ORM produces an additional query for each associated row you’re fetching. This can be solved by using
prefetch_related() methods when making queries.
When a table has a lot of columns, loading every column on each query has a potential to ruin your performance. Leave out the columns you don’t need and fetch the ones that you’re going to use: using
only() ORM methods will solve this problem.