Giả sử tôi muốn hiển thị danh sách các vận động viên được sắp xếp theo thời gian chạy nước rút mới nhất của họ.Django: Đặt hàng QuerySet dựa trên trường mô hình con mới nhất
class Runner(models.Model):
name = models.CharField(max_length=255)
class Sprint(models.Model):
runner = models.ForeignKey(Runner)
time = models.PositiveIntegerField()
created = models.DateTimeField(auto_now_add=True)
Đây là một phác thảo nhanh chóng của những gì tôi sẽ làm gì trong SQL:
SELECT runner.id, runner.name, sprint.time
FROM runner
LEFT JOIN sprint ON (sprint.runner_id = runner.id)
WHERE
sprint.id = (
SELECT sprint_inner.id
FROM sprint as sprint_inner
WHERE sprint_inner.runner_id = runner.id
ORDER BY sprint_inner.created DESC
LIMIT 1
)
OR sprint.id = NULL
ORDER BY sprint.time ASC
Các Django QuerySet documentation trạng thái:
Nó được phép chỉ định một lĩnh vực có nhiều giá trị ra lệnh kết quả bởi (ví dụ, trường ManyToManyField). Thông thường, điều này sẽ không phải là một điều hợp lý để thực hiện và nó thực sự là một tính năng sử dụng nâng cao . Tuy nhiên, nếu bạn biết rằng bộ lọc hoặc dữ liệu có sẵn của bộ truy vấn ngụ ý rằng sẽ chỉ có một phần dữ liệu cho mỗi các mục chính bạn đang chọn, thứ tự có thể chính xác là những gì bạn muốn làm. Sử dụng đặt hàng trên các lĩnh vực đa giá trị cẩn thận và đảm bảo kết quả là những gì bạn mong đợi.
Tôi đoán tôi cần phải áp dụng một số bộ lọc ở đây, nhưng tôi không chắc chắn chính xác những gì Django hy vọng ...
Một lưu ý vì nó không phải là rõ ràng trong ví dụ này: bảng Runner sẽ có nhiều hàng trăm mục, chạy nước rút cũng sẽ có hàng trăm và trong một số ngày sau đó có thể vài nghìn mục. Dữ liệu sẽ được hiển thị trong chế độ xem được phân trang, do đó việc sắp xếp trong Python không phải là một tùy chọn.
Khả năng duy nhất khác tôi thấy là tự viết SQL, nhưng tôi muốn tránh điều này bằng mọi giá.
Điều này có gây ra việc sử dụng bộ nhớ tương đối cao không? Theo như tôi có thể thấy nó kéo ít nhất mỗi người chạy vào bộ nhớ và xây dựng một danh sách khá lớn các id chạy nước rút của họ. Làm điều này trên mỗi lần xem trang với hàng trăm người chạy trong DB khiến tôi cảm thấy một chút * không thoải mái. Đây là nơi mà bộ nhớ đệm đá vào, tôi đoán vậy. – Strayer
Sau khi thử nghiệm điều này với 10.000 người chạy nó đã sử dụng RAM dưới 10MB (3MB thực sự…). Nếu bạn nghĩ rằng bạn sẽ cần nhiều hơn thế, bạn thực sự nên sử dụng SQL thô. Như mọi khi, cách tiếp cận tốt nhất để làm điều này là để hồ sơ đầu tiên - không suy đoán. Tối ưu hóa sớm và tất cả những điều đó ... – Matt
Và, một vài trăm bản ghi thực sự không nhiều ... chắc chắn không đủ để đảm bảo lo lắng về tối ưu hóa hiệu suất. Một vài trăm nghìn bản ghi thường là nơi bạn sẽ bắt đầu suy nghĩ về nó, và thậm chí sau đó nó thường không nhiều của một vấn đề (quăng trong một hoặc hai chỉ số và nó được giải quyết). – Matt