Sebagian besar implementasi DBAPI sepenuhnya buffer baris saat diambil - jadi biasanya, bahkan sebelum SQLAlchemy ORM mendapatkan satu hasil, seluruh kumpulan hasil ada di memori.
Tapi kemudian, cara Query
kerjanya adalah itu sepenuhnya memuat hasil yang diberikan set secara default sebelum mengembalikan kepada Anda objek Anda. Alasan di sini menganggap kueri yang lebih dari sekadar pernyataan SELECT. Misalnya, dalam penggabungan ke tabel lain yang mungkin mengembalikan identitas objek yang sama beberapa kali dalam satu set hasil (umum dengan eager loading), set baris lengkap perlu berada dalam memori sehingga hasil yang benar dapat dikembalikan jika tidak koleksi dan semacamnya. mungkin hanya terisi sebagian.
Jadi Query
menawarkan opsi untuk mengubah perilaku ini yield_per()
. Panggilan ini akan menyebabkan Query
untuk menghasilkan baris dalam kelompok, di mana Anda memberinya ukuran kelompok. Seperti yang dinyatakan oleh dokumen, ini hanya sesuai jika Anda tidak melakukan pemuatan koleksi apa pun sehingga pada dasarnya Anda benar-benar tahu apa yang Anda lakukan. Selain itu, jika baris pra-buffer DBAPI yang mendasari, masih akan ada overhead memori sehingga pendekatannya hanya berskala sedikit lebih baik daripada tidak menggunakannya.
Saya hampir tidak pernah menggunakan yield_per()
; sebaliknya, saya menggunakan versi yang lebih baik dari pendekatan LIMIT yang Anda sarankan di atas menggunakan fungsi jendela. LIMIT dan OFFSET memiliki masalah besar sehingga nilai OFFSET yang sangat besar menyebabkan kueri menjadi lebih lambat dan lebih lambat, karena OFFSET dari N menyebabkannya halaman melalui baris N - ini seperti melakukan kueri yang sama lima puluh kali daripada satu, setiap kali membaca a jumlah baris yang lebih besar dan lebih besar. Dengan pendekatan fungsi jendela, saya mengambil terlebih dahulu satu set nilai "jendela" yang mengacu pada potongan tabel yang ingin saya pilih. Saya kemudian memancarkan pernyataan SELECT individu yang masing-masing menarik dari salah satu jendela itu pada satu waktu.
Pendekatan fungsi jendela ada di wiki dan saya menggunakannya dengan sangat sukses.
Perhatikan juga: tidak semua database mendukung fungsi jendela; Anda membutuhkan Postgresql, Oracle, atau SQL Server. IMHO menggunakan setidaknya Postgresql pasti sepadan - jika Anda menggunakan database relasional, Anda mungkin juga menggunakan yang terbaik.