Hầu hết các triển khai DBAPI đều đệm đầy đủ các hàng khi chúng được tìm nạp - vì vậy thông thường, trước khi SQLAlchemy ORM nhận được một kết quả, toàn bộ tập kết quả sẽ nằm trong bộ nhớ.
Nhưng sau đó, cách Query
hoạt động là nó tải hoàn toàn kết quả đã cho được đặt theo mặc định trước khi trả về cho bạn các đối tượng của bạn. Sự hợp lý ở đây liên quan đến các truy vấn không chỉ là các câu lệnh SELECT đơn giản. Ví dụ: trong các phép nối đến các bảng khác có thể trả về cùng một đối tượng nhiều lần trong một tập kết quả (phổ biến với tải nhanh), tập hợp đầy đủ các hàng cần phải có trong bộ nhớ để có thể trả về kết quả chính xác, nếu không thì các tập hợp và tương tự có thể chỉ được điền một phần.
Vì vậy, Query
cung cấp một tùy chọn để thay đổi hành vi này thông qua yield_per()
. Lệnh gọi này sẽ tạo ra các Query
hàng theo lô, nơi bạn cung cấp cho nó kích thước lô. Như trạng thái tài liệu, điều này chỉ thích hợp nếu bạn không thực hiện bất kỳ loại tải bộ sưu tập háo hức nào, vì vậy về cơ bản nó là nếu bạn thực sự biết mình đang làm gì. Ngoài ra, nếu các hàng DBAPI bên dưới bộ đệm trước, sẽ vẫn có chi phí bộ nhớ đó nên cách tiếp cận chỉ có quy mô tốt hơn một chút so với việc không sử dụng nó.
Tôi hầu như không bao giờ sử dụng yield_per()
; thay vào đó, tôi sử dụng phiên bản tốt hơn của phương pháp LIMIT mà bạn đề xuất ở trên bằng cách sử dụng các hàm cửa sổ. LIMIT và OFFSET có một vấn đề lớn là các giá trị OFFSET rất lớn khiến truy vấn ngày càng chậm hơn, vì OFFSET của N khiến nó chuyển trang qua N hàng - giống như thực hiện cùng một truy vấn năm mươi lần thay vì một, mỗi lần đọc một số lượng hàng lớn hơn và lớn hơn. Với cách tiếp cận hàm cửa sổ, tôi tìm nạp trước một tập hợp các giá trị "cửa sổ" tham chiếu đến các phần của bảng mà tôi muốn chọn. Sau đó, tôi phát ra các câu lệnh SELECT riêng lẻ mà mỗi câu lệnh kéo từ một trong các cửa sổ đó tại một thời điểm.
Phương pháp tiếp cận chức năng cửa sổ có trên wiki và tôi sử dụng nó rất thành công.
Cũng lưu ý: không phải tất cả các cơ sở dữ liệu đều hỗ trợ các chức năng cửa sổ; bạn cần Postgresql, Oracle hoặc SQL Server. IMHO sử dụng ít nhất Postgresql chắc chắn đáng giá - nếu bạn đang sử dụng cơ sở dữ liệu quan hệ, bạn cũng có thể sử dụng tốt nhất.