Tại sao nó chậm :Nếu bạn chỉ sử dụng chú thích của hai trường ManyToMany thì bạn tạo một nối lớn không mong muốn của tất cả các bảng này cùng với nhau. Kích thước của tích Descartes của các hàng phải được đánh giá là khoảng Have.objects.count() * Want.objects.count()
. Sau đó bạn đã viết distinct=True
cuối cùng để hạn chế số lượng các mục trùng lặp để không nhận được một kết quả khổng lồ không hợp lệ.
Khắc phục cho Django cũ:Nếu bạn chỉ sử dụng queryset.annotate(have_count=Count("have"))
bạn sẽ nhanh chóng nhận được kết quả phù hợp mà không cần distinct=True
hoặc cùng một kết quả cũng nhanh chóng với khác biệt. Sau đó, bạn có thể kết hợp kết quả của hai truy vấn bằng Python trong bộ nhớ.
Giải pháp Một giải pháp tốt có thể thực hiện được trong Django> =1.11 (hai năm sau câu hỏi của bạn) bằng cách sử dụng truy vấn với hai truy vấn phụ , một cho Have
và một cho Want
, tất cả theo một yêu cầu, nhưng không kết hợp tất cả các bảng với nhau.
from django.db.models import Count, OuterRef, Subquery
sq = Collection.objects.filter(pk=OuterRef('pk')).order_by()
have_count_subq = sq.values('have').annotate(have_count=Count('have')).values('have_count')
want_count_subq = sq.values('want').annotate(have_count=Count('want')).values('want_count')
queryset = queryset.annotate(have_count=Subquery(have_count_subq),
want_count=Subquery(want_count_subq))
Xác minh :Bạn có thể kiểm tra cả truy vấn SQL chậm và cố định bằng cách in str(my_queryset.query)
rằng nó được mô tả ở trên.