Menggunakan buffering adaptif

Unduh driver JDBC

Buffer adaptif dirancang untuk mengambil segala jenis data berukuran besar tanpa overhead kursor server. Aplikasi dapat menggunakan fitur buffering adaptif dengan semua versi SQL Server yang didukung oleh driver.

Biasanya, ketika Driver Microsoft JDBC untuk SQL Server menjalankan kueri, driver mengambil semua hasil dari server ke dalam memori aplikasi. Meskipun pendekatan ini meminimalkan konsumsi sumber daya pada SQL Server, pendekatan ini dapat melemparkan OutOfMemoryError di aplikasi JDBC untuk kueri yang menghasilkan hasil yang sangat besar.

Untuk memungkinkan aplikasi menangani hasil yang sangat besar, Microsoft JDBC Driver untuk SQL Server menyediakan buffering adaptif. Dengan buffering adaptif, driver mengambil hasil eksekusi pernyataan dari SQL Server saat aplikasi membutuhkannya, bukan sekaligus. Driver juga membuang hasilnya segera setelah aplikasi tidak dapat lagi mengaksesnya. Berikut ini adalah beberapa contoh di mana buffering adaptif dapat berguna:

  • Kueri menghasilkan tataan hasil yang sangat besar: Aplikasi dapat menjalankan pernyataan SELECT yang menghasilkan lebih banyak baris daripada yang dapat disimpan aplikasi dalam memori. Dalam rilis sebelumnya, aplikasi harus menggunakan kursor server untuk menghindari OutOfMemoryError. Buffering adaptif memungkinkan pembacaan satu arah yang hanya-baca atas kumpulan hasil berukuran seberapa pun tanpa memerlukan kursor server.

  • Kueri menghasilkan kolom SQLServerResultSet yang sangat besaratau nilai parameter SQLServerCallableStatementOUT: Aplikasi dapat mengambil satu nilai (kolom atau parameter OUT) yang terlalu besar agar pas sepenuhnya dalam memori aplikasi. Buffering adaptif memungkinkan aplikasi klien untuk mengambil nilai seperti aliran, dengan menggunakan metode getAsciiStream, getBinaryStream, atau getCharacterStream. Aplikasi mengambil nilai dari SQL Server saat membaca dari stream.

Catatan

Dengan buffering adaptif, driver JDBC hanya menyimpan data sebanyak yang diperlukan. Driver tidak menyediakan metode publik untuk mengontrol atau membatasi ukuran buffer.

Mengatur buffering adaptif

Dimulai dengan driver JDBC versi 2.0, perilaku default driver adalah "adaptif". Dengan kata lain, untuk mendapatkan perilaku buffering adaptif, aplikasi Anda tidak perlu meminta perilaku adaptif secara eksplisit. Namun, dalam rilis versi 1.2, mode buffering "penuh" secara default dan aplikasi harus meminta mode buffering adaptif secara eksplisit.

Ada tiga cara agar aplikasi dapat meminta eksekusi pernyataan tersebut harus menggunakan buffering adaptif:

Saat menggunakan Driver JDBC versi 1.2, aplikasi perlu mentransmisikan objek pernyataan ke kelas SQLServerStatement untuk menggunakan metode setResponseBuffering . Contoh kode dalam sampel Membaca data besar dan sampel Membaca data besar dengan prosedur tersimpan menunjukkan penggunaan lama ini.

Namun, dengan driver JDBC versi 2.0, aplikasi dapat menggunakan metode isWrapperFor dan metode unwrap untuk mengakses fungsionalitas khusus vendor tanpa asumsi tentang hierarki kelas implementasi. Untuk contoh kode, lihat topik Memperbarui sampel data besar.

Mengambil data berukuran besar dengan buffering adaptif

Ketika nilai besar dibaca sekali dengan menggunakan metode get<Type>Stream, dan kolom ResultSet dan parameter CallableStatement OUT diakses dalam urutan yang dikembalikan oleh SQL Server, buffering adaptif meminimalkan penggunaan memori aplikasi saat memproses hasilnya. Saat menggunakan buffering adaptif:

  • Metode get<Type>Stream yang didefinisikan dalam kelas SQLServerResultSet dan SQLServerCallableStatement secara default mengembalikan stream yang hanya dapat dibaca sekali, meskipun stream tersebut dapat diatur ulang jika telah ditandai oleh aplikasi. Jika aplikasi ingin reset aliran tersebut, aplikasi harus terlebih dahulu memanggil metode mark pada aliran tersebut.

  • Metode get<Type>Stream yang ditentukan dalam kelas SQLServerClob dan SQLServerBlob mengembalikan aliran yang selalu dapat diposisikan ulang ke posisi awal aliran tanpa memanggil mark metode .

Ketika aplikasi menggunakan buffering adaptif, nilai yang diambil oleh metode get<Type>Stream hanya dapat diambil sekali. Jika Anda mencoba memanggil metode get<Type> apa pun pada kolom atau parameter yang sama setelah memanggil metode get<Type>Stream dari objek yang sama, pengecualian dilemparkan dengan pesan, "Data telah diakses dan tidak tersedia untuk kolom atau parameter ini".

Catatan

Panggilan ke ResultSet.close() di tengah pemrosesan ResultSet akan mengharuskan Driver Microsoft JDBC untuk SQL Server membaca dan membuang semua paket yang tersisa. Ini mungkin memakan waktu yang cukup lama jika kueri mengembalikan himpunan data besar dan terutama jika koneksi jaringan lambat.

Panduan untuk menggunakan buffering adaptif

Pengembang harus mengikuti panduan penting ini untuk meminimalkan penggunaan memori oleh aplikasi:

  • Hindari menggunakan properti string koneksi selectMethod=cursor agar aplikasi dapat memproses kumpulan hasil yang sangat besar. Fitur penyanggaan adaptif memungkinkan aplikasi memproses kumpulan hasil yang sangat besar, hanya-maju dan baca-saja, tanpa menggunakan kursor server. Perlu dicatat bahwa ketika Anda mengatur selectMethod=cursor, semua set hasil hanya-maju dan hanya-baca yang dihasilkan oleh koneksi tersebut akan terpengaruh. Dengan kata lain, jika aplikasi Anda secara rutin memproses tataan hasil pendek dengan beberapa baris, membuat, membaca, dan menutup kursor server untuk setiap kumpulan hasil akan menggunakan lebih banyak sumber daya di sisi klien dan sisi server daripada kasus di mana selectMethod tidak diatur ke kursor.

  • Baca teks besar atau nilai biner sebagai aliran dengan menggunakan metode getAsciiStream, getBinaryStream, atau getCharacterStream alih-alih metode getBlob atau getClob. Dimulai dengan rilis versi 1.2, kelas SQLServerCallableStatement menyediakan metode get<Type>Stream baru untuk tujuan ini.

  • Pastikan bahwa kolom dengan nilai yang berpotensi besar ditempatkan terakhir dalam daftar kolom dalam pernyataan SELECT dan bahwa metode get<Type>Stream dari SQLServerResultSet digunakan untuk mengakses kolom dalam urutan dipilih.

  • Pastikan bahwa parameter OUT dengan nilai yang berpotensi besar dinyatakan terakhir dalam daftar parameter di SQL yang digunakan untuk membuat SQLServerCallableStatement. Selain itu, pastikan bahwa metode get<Type>Stream dari SQLServerCallableStatement digunakan untuk mengakses parameter OUT dalam urutan yang dideklarasikan.

  • Hindari menjalankan lebih dari satu pernyataan pada koneksi yang sama secara bersamaan. Menjalankan pernyataan lain sebelum memproses hasil pernyataan sebelumnya dapat menyebabkan hasil yang tidak diproses di-buffer ke dalam memori aplikasi.

  • Ada beberapa kasus saat menggunakan selectMethod=cursor alih-alih responseBuffering=adaptive akan lebih bermanfaat, seperti:

    • Jika aplikasi Anda memproses kumpulan hasil khusus maju dan hanya-baca dengan lambat, misalnya membaca setiap baris setelah ada masukan dari pengguna, penggunaan selectMethod=cursor alih-alih responseBuffering=adaptive dapat membantu mengurangi penggunaan sumber daya di SQL Server.

    • Jika aplikasi Anda memproses dua atau lebih kumpulan hasil maju-saja dan hanya-baca secara bersamaan pada koneksi yang sama, penggunaan selectMethod=cursor alih-alih responseBuffering=adaptive dapat membantu mengurangi memori yang diperlukan driver saat memproses kumpulan hasil ini.

    Dalam kedua kasus, Anda perlu mempertimbangkan beban tambahan dalam membuat, membaca, dan menutup kursor server.

Selain itu, daftar berikut ini memuat beberapa rekomendasi untuk set hasil yang dapat digulir dan dapat diperbarui dengan pergerakan maju saja:

  • Untuk kumpulan hasil yang dapat digulir, saat mengambil satu blok baris, driver selalu membaca ke dalam memori sejumlah baris yang ditunjukkan oleh metode getFetchSize dari objek SQLServerResultSet, bahkan ketika buffering adaptif diaktifkan. Jika pengguliran menyebabkan OutOfMemoryError, Anda dapat mengurangi jumlah baris yang diambil dengan memanggil metode setFetchSize dari objek SQLServerResultSet untuk mengatur ukuran pengambilan ke jumlah baris yang lebih kecil, bahkan hingga 1 baris, jika perlu. Jika ini tidak mencegah OutOfMemoryError, hindari menyertakan kolom yang sangat besar dalam tataan hasil yang dapat digulir.

  • Untuk kumpulan hasil yang hanya-maju dan dapat diperbarui, saat mengambil satu blok baris, driver biasanya membaca ke dalam memori sejumlah baris yang ditentukan oleh metode getFetchSize dari objek SQLServerResultSet, bahkan ketika buffering adaptif diaktifkan untuk koneksi. Jika memanggil metode objek SQLServerResultSet berikutnya menghasilkan OutOfMemoryError, Anda dapat mengurangi jumlah baris yang diambil dengan memanggil metode setFetchSize objek SQLServerResultSet untuk mengatur ukuran pengambilan ke jumlah baris yang lebih kecil, bahkan hingga 1 baris, jika perlu. Anda juga dapat memaksa driver untuk tidak menyangga baris apa pun dengan memanggil metode setResponseBuffering objek SQLServerStatement dengan parameter "adaptif" sebelum menjalankan pernyataan. Karena kumpulan hasil tidak dapat digulir, jika aplikasi mengakses nilai kolom besar dengan menggunakan salah satu metode get<Type>Stream, driver membuang nilai segera setelah aplikasi membacanya seperti yang dilakukan untuk kumpulan hasil baca-saja.