Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Prosedur tersimpan Oracle, mengembalikan kursor ref vs array asosiatif

Permintaan DBA tidak masuk akal.

Apa yang hampir pasti dipikirkan oleh DBA adalah bahwa ia ingin meminimalkan jumlah pergeseran konteks mesin SQL ke PL/SQL yang terjadi saat Anda mengambil data dari kursor. Namun solusi yang disarankan tidak tepat sasaran pada masalah khusus ini dan menimbulkan masalah kinerja lain yang jauh lebih serius di sebagian besar sistem.

Di Oracle, pergeseran konteks SQL ke PL/SQL terjadi ketika VM PL/SQL meminta lebih banyak data kepada SQL VM, SQL VM merespons dengan mengeksekusi pernyataan lebih lanjut untuk mendapatkan data yang kemudian dikemas dan diserahkan kembali ke PL /SQLVM. Jika mesin PL/SQL meminta baris satu per satu dan Anda mengambil banyak baris, ada kemungkinan bahwa pergeseran konteks ini dapat menjadi bagian yang signifikan dari keseluruhan runtime Anda. Untuk mengatasi masalah itu, Oracle memperkenalkan konsep operasi massal kembali setidaknya dalam 8i hari. Ini memungkinkan PL/SQL VM untuk meminta beberapa baris sekaligus dari SQL VM. Jika PL/SQL VM meminta 100 baris sekaligus, Anda telah menghilangkan 99% pergeseran konteks dan kode Anda berpotensi berjalan lebih cepat.

Setelah operasi massal diperkenalkan, ada banyak kode yang dapat difaktorkan ulang agar lebih efisien dengan secara eksplisit menggunakan BULK COLLECT operasi daripada mengambil baris demi baris dan kemudian menggunakan FORALL loop untuk memproses data dalam koleksi tersebut. Namun, dalam 10,2 hari, Oracle telah mengintegrasikan operasi massal ke dalam FOR implicit implisit loop sehingga implisit FOR loop sekarang secara otomatis mengumpulkan massal dalam batch 100 daripada mengambil baris demi baris.

Namun, dalam kasus Anda, karena Anda mengembalikan data ke aplikasi klien, penggunaan operasi massal jauh lebih tidak signifikan. Setiap API sisi klien yang layak akan memiliki fungsionalitas yang memungkinkan klien menentukan berapa banyak baris yang perlu diambil dari kursor di setiap perjalanan pulang pergi jaringan dan permintaan pengambilan tersebut akan langsung menuju ke SQL VM, bukan melalui PL /SQL VM, jadi tidak ada perubahan konteks SQL ke PL/SQL yang perlu dikhawatirkan. Aplikasi Anda harus khawatir tentang mengambil jumlah baris yang sesuai di setiap perjalanan pulang pergi-- cukup sehingga aplikasi tidak menjadi terlalu cerewet dan macet di jaringan tetapi tidak terlalu banyak sehingga Anda harus menunggu terlalu lama untuk hasilnya dikembalikan atau menyimpan terlalu banyak data dalam memori.

Mengembalikan koleksi PL/SQL daripada KURSOR REF ke aplikasi klien tidak akan mengurangi jumlah pergeseran konteks yang terjadi. Tapi itu akan memiliki banyak kelemahan lain yang paling tidak adalah penggunaan memori. Koleksi PL/SQL harus disimpan seluruhnya di area global proses (PGA) (dengan asumsi koneksi server khusus) di server database. Ini adalah sepotong memori yang harus dialokasikan dari RAM server. Itu berarti bahwa server harus mengalokasikan memori untuk mengambil setiap baris terakhir yang diminta setiap klien. Itu, pada gilirannya, akan secara dramatis membatasi skalabilitas aplikasi Anda dan, tergantung pada konfigurasi database, dapat mencuri RAM dari bagian lain dari database Oracle yang akan sangat berguna dalam meningkatkan kinerja aplikasi. Dan jika Anda kehabisan ruang PGA, sesi Anda akan mulai mendapatkan kesalahan terkait memori. Bahkan dalam aplikasi murni berbasis PL/SQL, Anda tidak akan pernah ingin mengambil semua data ke dalam koleksi, Anda selalu ingin mengambilnya dalam batch yang lebih kecil, untuk meminimalkan jumlah PGA yang Anda gunakan.

Selain itu, mengambil semua data ke dalam memori akan membuat aplikasi terasa jauh lebih lambat. Hampir semua kerangka kerja akan memungkinkan Anda mengambil data sesuai kebutuhan, misalnya, jika Anda memiliki laporan yang ditampilkan di halaman masing-masing 25 baris, aplikasi Anda hanya perlu mengambil 25 baris pertama sebelum mengecat layar pertama. Dan itu tidak akan pernah mengambil 25 baris berikutnya kecuali jika pengguna meminta halaman hasil berikutnya. Namun, jika Anda mengambil data ke dalam array seperti yang diusulkan DBA, Anda harus mengambil semua baris sebelum aplikasi Anda dapat mulai menampilkan baris pertama meskipun pengguna tidak pernah ingin melihat lebih dari segelintir pertama baris. Itu berarti lebih banyak I/O di server database untuk mengambil semua baris, lebih banyak PGA di server, lebih banyak RAM di server aplikasi untuk menyangga hasilnya, dan menunggu jaringan lebih lama.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Masalah kueri SqlPlus (Spesifikasi Paket dan Isi)

  2. Apakah dbms_output.put() di-buffer berbeda dari dbms_output.put_line()?

  3. Gabungkan node XMLType dalam kueri Oracle

  4. Mendapatkan ORA-01882:wilayah zona waktu tidak ditemukan dengan Oracle UCP, pada instance aws ec2?

  5. Pengidentifikasi Oracle Nhibernate Lancar Terlalu Panjang - Masalah Nama Alias