This code is currently executing about 50 SQL queries:
c = Category.objects.all()
categories_w_rand_books = []
for category in c:
r = Book.objects.filter(author__category=category).order_by('?')[:5]
categories_w_rand_books.append((category, r))
I need to cut down the number of used queries to the minimum to speed up things and do not cause server load.
Basically, I have three models: Category, Author, Book. The Author belong to the Category (not books) and I need to get a list of all categories with 5 random books under each one.
If you prefer single query and are using
MySQL, check the excellent link provided by @Crazyshezy in his comment.For
PostgreSQLbackends, a possible query is (assuming there are non-nullableFKrelationships fromBooktoAuthorand fromAuthortoCategory):You could then wrap it inside a
RawQuerySetto getBookinstancesYou may not want to run this query for each request directly w/o some caching.
Furthermore, your code generates at most 50*5=250
Books, randomly, I just wonder why because it seems too many for a single page. Are items displayed as tabs or something else? Perhaps you could reduce the counts of SQLs by doing Ajax, or simplify the requirement?Update
To use
book.authorw/o triggering more than another query, tryprefetch_related_objectsThe above code prefetches authors in batch and fills them into the
qs. This just adds another query.