Menggunakan buffering adaptif

Unduh driver JDBC

Buffering adaptif dirancang untuk mengambil segala jenis data bernilai 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, Driver Microsoft JDBC 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 memberikan kemampuan untuk melakukan pass baca-saja terusan dari tataan hasil yang sangat besar tanpa memerlukan kursor server.

  • Kueri menghasilkan kolom SQLServerResultSet yang sangat besar atau nilai parameter SQLServerCallableStatementOUT: Aplikasi dapat mengambil nilai tunggal (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 dibaca dari aliran.

Catatan

Dengan buffering adaptif, buffer driver JDBC hanya memiliki jumlah data 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 yang diperlukan untuk mentransmisikan objek pernyataan ke kelas SQLServerStatement untuk menggunakan metode setResponseBuffering . Contoh kode dalam sampel Membaca data besar dan Membaca data besar dengan sampel 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. Misalnya kode, lihat topik Memperbarui sampel data besar .

Mengambil data 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 hasil. Saat menggunakan buffering adaptif:

  • Metode get<Type>Stream yang ditentukan dalam kelas SQLServerResultSet dan SQLServerCallableStatement mengembalikan aliran baca-sekali secara default, meskipun aliran dapat diatur ulang jika ditandai oleh aplikasi. Jika aplikasi ingin reset melakukan streaming, aplikasi harus memanggil metode pada aliran tersebut mark terlebih dahulu.

  • 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 untuk memungkinkan aplikasi memproses tataan hasil yang sangat besar. Fitur buffering adaptif memungkinkan aplikasi untuk memproses tataan hasil baca-saja yang sangat besar tanpa menggunakan kursor server. Perhatikan bahwa saat Anda mengatur selectMethod=cursor, semua tataan hasil hanya-terusan, baca-saja yang dihasilkan oleh koneksi tersebut 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 yang dipilih.

  • Pastikan 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 hasil terusan saja dan baca-saja yang diatur secara perlahan, seperti membaca setiap baris setelah beberapa input pengguna, menggunakan selectMethod=cursor alih-alih responseBuffering=adaptive mungkin membantu mengurangi penggunaan sumber daya dengan SQL Server.

    • Jika aplikasi Anda memproses dua atau lebih set hasil baca-saja pada saat yang sama pada koneksi yang sama, menggunakan selectMethod=cursor alih-alih responseBuffering=adaptive mungkin membantu mengurangi memori yang diperlukan oleh driver saat memproses tataan hasil ini.

    Dalam kedua kasus, Anda perlu mempertimbangkan overhead untuk membuat, membaca, dan menutup kursor server.

Selain itu, daftar berikut ini memberikan beberapa rekomendasi untuk kumpulan hasil yang dapat digulir dan diperbarui khusus maju:

  • Untuk tataan hasil yang dapat digulir, saat mengambil blok baris, driver selalu membaca ke dalam memori jumlah baris yang ditunjukkan oleh metode getFetchSize dari objek SQLServerResultSet , bahkan ketika buffering adaptif diaktifkan. Jika menggulir 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 ke bawah ke 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 dapat diperbarui hanya maju, saat mengambil blok baris yang biasanya dibaca driver ke dalam memori jumlah baris yang ditunjukkan oleh metode getFetchSize dari objek SQLServerResultSet , bahkan ketika buffering adaptif diaktifkan pada koneksi. Jika memanggil metode berikutnya dari objek SQLServerResultSet menghasilkan 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. Anda juga dapat memaksa driver untuk tidak menyangga baris apa pun dengan memanggil metode setResponseBuffering objek SQLServerStatement dengan parameter "adaptif" sebelum menjalankan pernyataan. Karena tataan 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 halnya untuk kumpulan hasil baca-saja maju.

Lihat juga

Meningkatkan performa dan keandalan dengan driver JDBC