Rumah >pangkalan data >tutorial mysql >Bagaimanakah Saya Boleh Mengelakkan Penilaian Pelbagai Fungsi Apabila Menggunakan `(func()).*` dalam PostgreSQL?

Bagaimanakah Saya Boleh Mengelakkan Penilaian Pelbagai Fungsi Apabila Menggunakan `(func()).*` dalam PostgreSQL?

DDD
DDDasal
2025-01-10 11:19:42458semak imbas

How Can I Avoid Multiple Function Evaluations When Using `(func()).*` in PostgreSQL?

*Elakkan menggunakan `(func()).` dalam PostgreSQL untuk menyebabkan panggilan fungsi berulang**

Dalam PostgreSQL, menggunakan sintaks (func()).* untuk mengakses hasil fungsi yang mengembalikan jadual atau jenis komposit boleh menyebabkan panggilan berulang ke fungsi untuk setiap lajur. Ini boleh memberi kesan kepada prestasi, terutamanya jika fungsi itu mahal dari segi pengiraan.

Penyelesaian

Untuk mengelakkan masalah ini, anda boleh membungkus panggilan fungsi dalam subquery seperti ini:

<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>

Ini memastikan bahawa fungsi dipanggil sekali sahaja, tidak kira berapa banyak lajur dalam hasilnya. Sebagai alternatif, dalam PostgreSQL 9.3 dan lebih baru, anda boleh menggunakan sintaks LATERAL JOIN:

<code class="language-sql">SELECT mf.*
FROM some_table
LEFT JOIN LATERAL my_func(some_table.x) AS mf ON true;</code>

Punca masalah

Panggilan berulang berlaku kerana penghurai menganggap (func()).* sebagai pemegang tempat untuk senarai nama lajur. Ia mengembangkan makro ungkapan ke dalam satu siri lajur yang berasingan, menghasilkan berbilang panggilan ke fungsi tersebut.

Demo

Untuk menunjukkan masalah dan penyelesaian, cipta fungsi:

<code class="language-sql">CREATE OR REPLACE FUNCTION my_func(integer)
RETURNS TABLE(a integer, b integer, c integer) AS $$
BEGIN
    RAISE NOTICE 'my_func(%)',;
    RETURN QUERY SELECT , , ;
END;
$$ LANGUAGE plpgsql;</code>

dan jadual yang mengandungi data tiruan:

<code class="language-sql">CREATE TABLE some_table AS SELECT x FROM generate_series(1,10) x;</code>

Bandingkan hasil pertanyaan berikut:

  • Sintaks asal:
<code class="language-sql">SELECT (my_func(x)).* FROM some_table;</code>
  • Sintaks penyelesaian:
<code class="language-sql">SELECT (mf).* FROM (
    SELECT my_func(x) AS mf FROM some_table
) sub;</code>

Anda akan perasan bahawa sintaks asal menimbulkan berbilang pemberitahuan, manakala sintaks penyelesaian hanya menimbulkan satu pemberitahuan, menunjukkan kesan mengelakkan panggilan berbilang fungsi.

Atas ialah kandungan terperinci Bagaimanakah Saya Boleh Mengelakkan Penilaian Pelbagai Fungsi Apabila Menggunakan `(func()).*` dalam PostgreSQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn