PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Bagaimana cara melewatkan satu set baris dari satu fungsi ke fungsi lainnya?

Fungsi tabel

Saya melakukan migrasi basis data yang sangat cepat dan kompleks untuk mencari nafkah, menggunakan SQL sebagai bahasa klien dan server (tidak ada bahasa lain yang digunakan), semua menjalankan sisi server, di mana kode jarang muncul dari mesin basis data. Fungsi tabel memainkan peran BESAR dalam pekerjaan saya . Saya tidak menggunakan "kursor" karena terlalu lambat untuk memenuhi persyaratan kinerja saya, dan semua yang saya lakukan berorientasi pada hasil. Fungsi tabel telah sangat membantu saya dalam sepenuhnya menghilangkan penggunaan kursor, mencapai kecepatan yang sangat tinggi, dan telah berkontribusi secara dramatis terhadap pengurangan volume kode dan meningkatkan kesederhanaan.

Singkatnya, Anda menggunakan kueri yang mereferensikan dua (atau lebih) fungsi tabel untuk meneruskan data dari satu fungsi tabel ke fungsi berikutnya. Set hasil kueri pemilihan yang memanggil fungsi tabel berfungsi sebagai saluran untuk meneruskan data dari satu fungsi tabel ke fungsi tabel berikutnya. Pada platform/versi DB2 yang saya kerjakan, dan itu muncul berdasarkan tampilan cepat pada manual 9.1 Postgres bahwa hal yang sama berlaku di sana, Anda hanya dapat melewatkan satu baris nilai kolom sebagai input ke salah satu panggilan fungsi tabel, seperti yang telah Anda temukan. Namun, karena panggilan fungsi tabel terjadi di tengah pemrosesan kumpulan hasil kueri, Anda mencapai efek yang sama dengan meneruskan seluruh kumpulan hasil ke setiap panggilan fungsi tabel, meskipun, di pipa mesin database, data dilewatkan hanya satu baris pada satu waktu untuk setiap fungsi tabel.

Fungsi tabel menerima satu baris kolom input, dan mengembalikan satu set hasil kembali ke kueri panggilan (yaitu pilih) yang memanggil fungsi. Kolom kumpulan hasil yang dikembalikan dari fungsi tabel menjadi bagian dari kumpulan hasil kueri pemanggilan, dan oleh karena itu tersedia sebagai input ke fungsi tabel berikutnya , direferensikan nanti dalam kueri yang sama, biasanya sebagai gabungan berikutnya. Kolom hasil fungsi tabel pertama diumpankan sebagai input (satu baris pada satu waktu) ke fungsi tabel kedua, yang mengembalikan kolom kumpulan hasil ke dalam kumpulan hasil kueri panggilan. Kolom kumpulan hasil fungsi tabel pertama dan kedua sekarang menjadi bagian dari kumpulan hasil kueri panggilan, dan sekarang tersedia sebagai input (satu baris setiap kali) ke fungsi tabel ketiga. Setiap panggilan fungsi tabel memperluas hasil kueri panggilan yang disetel melalui kolom yang dikembalikannya. Ini dapat berlangsung terus hingga Anda mulai mencapai batas lebar kumpulan hasil, yang kemungkinan bervariasi dari satu mesin basis data ke mesin basis data berikutnya.

Pertimbangkan contoh ini (yang mungkin tidak cocok dengan persyaratan atau kemampuan sintaks Postgres saat saya mengerjakan DB2). Ini adalah salah satu dari banyak pola desain di mana saya menggunakan fungsi tabel, adalah salah satu yang lebih sederhana, yang menurut saya sangat ilustratif, dan salah satu yang saya perkirakan akan memiliki daya tarik yang luas jika fungsi tabel digunakan secara umum (setahu saya tidak, tapi saya pikir mereka layak mendapat perhatian lebih dari yang mereka dapatkan).

Dalam contoh ini, fungsi tabel yang digunakan adalah:VALIDATE_TODAYS_ORDER_BATCH, POST_TODAYS_ORDER_BATCH, dan DATA_WAREHOUSE_TODAYS_ORDER_BATCH. Pada versi DB2 yang saya kerjakan, Anda membungkus fungsi tabel di dalam "TABLE( menempatkan panggilan fungsi tabel dan parameter di sini )", tetapi berdasarkan sekilas pada manual Postgres tampaknya Anda menghilangkan pembungkus "TABLE()".

create table TODAYS_ORDER_PROCESSING_EXCEPTIONS as (

select      TODAYS_ORDER_BATCH.*
           ,VALIDATION_RESULT.ROW_VALID
           ,POST_RESULT.ROW_POSTED
           ,WAREHOUSE_RESULT.ROW_WAREHOUSED

from        TODAYS_ORDER_BATCH

cross join  VALIDATE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function]  ) 
              as VALIDATION_RESULT ( ROW_VALID )  --example: 1/0 true/false Boolean returned

left join   POST_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
              as POST_RESULT ( ROW_POSTED )  --example: 1/0 true/false Boolean returned
      on    ROW_VALIDATED = '1'

left join   DATA_WAREHOUSE_TODAYS_ORDER_BATCH ( ORDER_NUMBER, [either pass the remainder of the order columns or fetch them in the function] )
              as WAREHOUSE_RESULT ( ROW_WAREHOUSED )  --example: 1/0 true/false Boolean returned
      on    ROW_POSTED = '1'

where       coalesce( ROW_VALID,      '0' ) = '0'   --Capture only exceptions and unprocessed work.  
      or    coalesce( ROW_POSTED,     '0' ) = '0'   --Or, you can flip the logic to capture only successful rows.
      or    coalesce( ROW_WAREHOUSED, '0' ) = '0'

) with data
  1. Jika tabel TODAYS_ORDER_BATCH berisi 1.000.000 baris, makaVALIDATE_TODAYS_ORDER_BATCH akan dipanggil 1.000.000 kali, sekali untuk setiap baris.
  2. Jika 900.000 baris lulus validasi di dalam VALIDATE_TODAYS_ORDER_BATCH, maka POST_TODAYS_ORDER_BATCH akan dipanggil 900.000 kali.
  3. Jika hanya 850.000 baris yang berhasil diposkan, maka VALIDATE_TODAYS_ORDER_BATCH perlu beberapa celah ditutup LOL, dan DATA_WAREHOUSE_TODAYS_ORDER_BATCH akan dipanggil 850.000 kali.
  4. Jika 850.000 baris berhasil masuk ke Data Warehouse (yaitu tidak ada pengecualian tambahan yang dibuat), maka tabel TODAYS_ORDER_PROCESSING_EXCEPTIONS akan diisi dengan 1.000.000 - 850.000 =150.000 baris pengecualian.

Panggilan fungsi tabel dalam contoh ini hanya mengembalikan satu kolom, tetapi mereka bisa mengembalikan banyak kolom. Misalnya, fungsi tabel yang memvalidasi baris pesanan dapat mengembalikan alasan mengapa pesanan gagal divalidasi.

Dalam desain ini, hampir semua obrolan antara HLL dan database dihilangkan, karena pemohon HLL meminta database untuk memproses seluruh batch dalam SATU permintaan. Ini menghasilkan pengurangan jutaan permintaan SQL ke database, dalam penghapusan BESAR dari jutaan panggilan prosedur atau metode HLL, dan sebagai hasilnya memberikan peningkatan runtime BESAR. Sebaliknya, kode lama yang sering memproses satu baris pada satu waktu, biasanya akan mengirim 1.000.000 permintaan pengambilan SQL, 1 untuk setiap baris di TODAYS_ORDER_BATCH, ditambah setidaknya 1.000.000 HLL dan/atau permintaan SQL untuk tujuan validasi, ditambah setidaknya 1.000.000 HLL dan /atau permintaan SQL untuk tujuan posting, ditambah 1.000.000 permintaan HLL dan/atau SQL untuk mengirim pesanan ke gudang data. Memang, menggunakan desain fungsi tabel ini, di dalam fungsi tabel permintaan SQL dikirim ke database, tetapi ketika database membuat permintaan untuk dirinya sendiri (yaitu dari dalam fungsi tabel), permintaan SQL dilayani lebih cepat (terutama dibandingkan dengan skenario warisan di mana pemohon HLL melakukan pemrosesan baris tunggal dari sistem jarak jauh, dengan kasus terburuk melalui WAN - OMG tolong jangan lakukan itu).

Anda dapat dengan mudah mengalami masalah kinerja jika Anda menggunakan fungsi tabel untuk "mengambil kumpulan hasil" dan kemudian menggabungkan kumpulan hasil tersebut ke tabel lain. Dalam hal ini, pengoptimal SQL tidak dapat memprediksi kumpulan baris apa yang akan dikembalikan dari fungsi tabel, dan karena itu tidak dapat mengoptimalkan gabungan ke tabel berikutnya. Oleh karena itu, saya jarang menggunakannya untuk mengambil kumpulan hasil, kecuali saya tahu bahwa kumpulan hasil akan menjadi jumlah baris yang sangat kecil, sehingga tidak menyebabkan masalah kinerja, atau saya tidak perlu bergabung ke tabel berikutnya.

Menurut pendapat saya, salah satu alasan mengapa fungsi tabel kurang dimanfaatkan adalah karena mereka sering dianggap hanya sebagai alat untuk mengambil kumpulan hasil, yang seringkali berkinerja buruk, sehingga mereka dihapuskan sebagai alat "buruk" untuk digunakan.

Fungsi tabel sangat berguna untuk mendorong lebih banyak fungsionalitas ke server, untuk menghilangkan sebagian besar obrolan antara server database dan program pada sistem jarak jauh, dan bahkan untuk menghilangkan obrolan antara server database dan program eksternal di server yang sama. Bahkan obrolan antar program di server yang sama membawa lebih banyak overhead daripada yang disadari banyak orang, dan sebagian besar tidak perlu. Inti dari kekuatan fungsi tabel terletak pada penggunaannya untuk melakukan tindakan di dalam pemrosesan kumpulan hasil.

Ada pola desain yang lebih canggih untuk menggunakan fungsi tabel yang dibangun di atas pola di atas, di mana Anda dapat memaksimalkan pemrosesan kumpulan hasil lebih jauh lagi, tetapi postingan ini sudah banyak diserap oleh sebagian besar orang.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. php cara menggunakan kotak pilih untuk mencari data dalam tampilan daftar (tabel)

  2. Laporan Tren PostgreSQL 2019:Cloud Pribadi vs. Publik, Migrasi, Kombinasi Basis Data &Alasan Utama Digunakan

  3. Apa yang dapat menyebabkan idle dalam transaksi untuk pernyataan BEGIN

  4. Bisakah saya menggunakan kata kunci Postgres sebagai alias dalam daftar pilihan?

  5. Cara Menutup Celah Kerentanan di PostgreSQL