2011-10-31 24 views
7

Chú thích Django là tuyệt vời cho trung bình, tối thiểu/tối đa, v.v. Vậy điều đó có tạo ra cùng một SQL như thể tôi đã sử dụng số .count() cũ hơn trên queryset không? Hay nó tạo ra SQL hiệu quả hơn trong một số trường hợp? Hoặc tệ hơn SQL? Xin vui lòng, để làm rõ, tôi có nghĩa là để so sánh các hoạt động count() chống lại một cái gì đó như tổng hợp (Count ('id')) trong đó id là PK của bảng.Trong django, là tổng hợp (Count()) nhanh hơn hoặc tốt hơn .count() trong anyway?

Vì vậy, với điều đó, tôi tin rằng Brian có câu trả lời đúng. Tóm lại, count() chỉ đơn giản là một trường hợp đặc biệt của aggregate().

Trả lời

8

Gọi phương thức .count() của truy vấn cuối cùng gọi Count().

Cụ thể: django.db.models.QuerySet.count() cuộc gọi django.db.models.sql.Query.get_count(), trong đó kêu gọi django.db.models.sql.Query.add_count_column(), mà thêm django.db.models.sql.aggregates.Count vào truy vấn.

Sự khác biệt chính giữa hai là khi bạn sử dụng Count trực tiếp, bạn chỉ định các trường bạn muốn đếm, trong khi đó khi bạn gọi .count() trên queryset, điều này sẽ dẫn đến SELECT COUNT(*)... (trừ khi bạn cũng sử dụng riêng biệt() hoặc khi bạn giới hạn các trường trong mệnh đề select, trong trường hợp đó nó phức tạp hơn).

1

Táo và cam. .count() tính số lượng SQL trên bộ truy vấn hiện tại. Tuy nhiên, tổng hợp Count chạy số lượng các mối quan hệ bạn chỉ định trên bộ truy vấn.

Pizza.objects.count() # Total amount of pizzas 

Pizza.objects.aggregate(topping_count=Count('toppings')) # Total amount of toppings associated to a pizza 

Pizza.objects.annotate(topping_count=Count('toppings')) # Total amount of toppings on each pizza 
+0

Giả sử Pizza và Topping có mối quan hệ m2m, gọi tổng hợp trên Pizza như trong dòng thứ hai của bạn sẽ không trả về tổng số lớp trên bề mặt cho mỗi bánh pizza; nó sẽ tham gia bên ngoài Pizza để đứng đầu và về cơ bản đếm số lượng tham gia. Để có được số lượng lớp trên cùng cho mỗi bánh pizza, bạn cần sử dụng chú thích() thay vì aggreate(). –

+0

Xin lỗi. Tôi đã đi vào mô tả của tôi về những gì được trả về bởi tổng hợp. Cập nhật mô tả và thêm phiên bản 'chú thích' để làm nổi bật sự khác biệt –

+0

Nếu đứng đầu được gắn với nhiều hơn một bánh pizza, nó sẽ được kết hợp với nhiều pizza trong' Pizza.objects.aggregate (topping_count = Count ('toppings')) ' và do đó số lượng này sẽ trở lại nhiều hơn tổng số lớp trên bề mặt. Để có được tổng số lớp trên bề mặt được gắn với một chiếc bánh pizza (không tính trùng lặp), bạn có thể muốn làm một cái gì đó như 'Topping.objects.exclude (pizza_set = None) .count()'. –

Các vấn đề liên quan