(func()).*
Menggunakan sintaks (func()).*
dalam PostgreSQL untuk mengakses hasil daripada fungsi yang mengembalikan jenis komposit atau TABLE
boleh membawa kepada isu prestasi disebabkan penilaian fungsi yang berulang. Ini berlaku kerana sintaks berkembang menjadi rujukan berbilang lajur, setiap satu mencetuskan panggilan fungsi yang berasingan. Bilangan panggilan sama dengan bilangan lajur dalam set hasil.
Masalahnya: Panggilan Pelbagai Fungsi yang Tidak Cekap
Pendekatan (func()).*
adalah tidak cekap kerana ia tidak mengoptimumkan untuk panggilan fungsi yang minimum. Sebaik-baiknya, fungsi perlu dipanggil sekali sahaja untuk mendapatkan keseluruhan set hasil.
Penyelesaian:
PostgreSQL 9.3 dan kemudian menawarkan penyelesaian yang mudah menggunakan LATERAL
bergabung:
<code class="language-sql">SELECT mf.* FROM some_table LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>
LATERAL
memastikan bahawa my_func
dilaksanakan sekali sahaja setiap baris dalam some_table
, meningkatkan prestasi dengan ketara.
Untuk versi PostgreSQL yang lebih lama (sebelum 9.3), penyelesaian diperlukan:
Penyelesaian 1: OFFSET 0
Hack
Kaedah ini memanfaatkan klausa OFFSET 0
untuk memaksa penilaian fungsi tunggal:
<code class="language-sql">SELECT (mf).* FROM ( SELECT my_func(x) AS mf FROM some_table OFFSET 0 ) sub;</code>
Penyelesaian 2: Ungkapan Jadual Biasa (CTE)
CTE menyediakan alternatif yang lebih bersih:
<code class="language-sql">WITH tmp AS ( SELECT my_func(x) FROM some_table ) SELECT (mf).* FROM tmp;</code>
Kedua-dua penyelesaian memastikan my_func
dipanggil sekali sahaja, mendapatkan set hasil lengkap sebelum mengakses lajur individu.
Punca Punca: Peluasan Parser
Berbilang penilaian timbul daripada cara penghurai PostgreSQL mentafsir (func()).*
. Ia menterjemahkannya ke dalam akses lajur yang berasingan, menghasilkan pelbagai panggilan fungsi. Had ini telah ditangani dalam versi yang lebih baharu dengan pengenalan LATERAL
menyertai.
Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Penilaian Pelbagai Fungsi dengan Sintaks `(func()).*` PostgreSQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!