django select_related - when to use it

前端 未结 4 1259
挽巷
挽巷 2020-12-08 04:54

I\'m trying to optimize my ORM queries in django. I use connection.queries to view the queries that django generate for me.

Assuming I have these models:

<         


        
4条回答
  •  爱一瞬间的悲伤
    2020-12-08 05:13

    Django doesn't know about other queries! Author.objects.all() and Book.objects.all() are totally different querysets. So if have both in your view and pass them to template context but in your template you do something like:

    {% for book in books %}
      {{ book.author.name }}
    {% endfor %}
    

    and have N books this will result to N extra database queries (beyond the queries to get all books and authors) !

    If instead you had done Book.objects.all().select_related("author") no extra queries will be done in the above template snippet.

    Now, select_related() of course adds some overhead to the queries. What happens is that when you do a Book.objects.all() django will return the result of SELECT * FROM BOOKS. If instead you do a Book.objects.all().select_related("author") django will return the result of SELECT * FROM BOOKS B LEFT JOIN AUTHORS A ON B.AUTHOR_ID = A.ID. So for each book it will return both the columns of the book and its corresponding author. However, this overhead is really much smaller when compared to the overhead of hitting the database N times (as explained before).

    So, even though select_related creates a small performance overhead (each query returns more fields from the database) it will actually be beneficial to use it except when you are totally sure that you'll need only the columns of the specific model you are querying.

    Finally, a great way to really see how many (and which exactly) queries are actuall exectuted in your database is to use django-debug-tooblar (https://github.com/django-debug-toolbar/django-debug-toolbar).

提交回复
热议问题