user
Saat menulis ulang fungsi Anda, saya menyadari bahwa Anda menambahkan alias kolom di sini:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. yang tidak akan melakukan apa-apa untuk memulainya, karena alias tersebut tidak terlihat di luar fungsi dan tidak direferensikan di dalam fungsi. Jadi mereka akan diabaikan. Untuk tujuan dokumentasi lebih baik gunakan komentar.
Tapi itu juga membuat kueri Anda tidak valid , karena user
adalah kata khusus dan tidak dapat digunakan sebagai alias kolom kecuali tanda kutip ganda.
Anehnya, dalam pengujian saya, fungsi tersebut tampaknya berfungsi dengan alias yang tidak valid. Mungkin karena diabaikan (?). Tapi saya tidak yakin ini tidak memiliki efek samping.
Fungsi Anda ditulis ulang (jika tidak setara):
CREATE OR REPLACE FUNCTION get_web_events_by_userid(int)
RETURNS TABLE(
id int
, time_stamp timestamptz
, description text
, origin text
, userlogin text
, customer text
, client_ip inet
) AS
$func$
SELECT w.id
, w.time_stamp
, w.description
, w.origin
, u.email -- AS user -- make this a comment!
, c.name -- AS customer
, w.client_ip
FROM public.auth_user u
JOIN public.auth_web_events w ON w.user_id_fk = u.id
JOIN public.customers c ON c.id = u.customer_id_fk
WHERE u.id = $1 -- reverted the logic here
ORDER BY w.id DESC
$func$ LANGUAGE sql STABLE;
Jelas, STABLE
kata kunci mengubah hasilnya. Volatilitas fungsi seharusnya tidak menjadi masalah dalam situasi pengujian yang Anda gambarkan. Pengaturan biasanya tidak menguntungkan satu panggilan fungsi yang terisolasi. Baca detailnya di manual. Juga, EXPLAIN
standard standar tidak menampilkan rencana kueri untuk apa yang terjadi di dalam fungsi. Anda dapat menggunakan modul tambahan penjelasan otomatis untuk itu:
- Rencana kueri postgres dari permintaan UDF yang ditulis dalam pgpsql
Anda memiliki distribusi data yang sangat aneh :
tabel auth_web_events memiliki 100000000 catatan, auth_user->2 catatan, pelanggan-> 1 catatan
Karena Anda tidak mendefinisikan sebaliknya, fungsi mengasumsikan perkiraan 1000 baris untuk dikembalikan. Tetapi fungsi Anda sebenarnya hanya mengembalikan 2 baris . Jika semua panggilan Anda hanya kembali (di sekitar) 2 baris, nyatakan saja dengan ROWS 2
tambahan . Mungkin mengubah rencana kueri untuk VOLATILE
varian juga (bahkan jika STABLE
adalah pilihan yang tepat di sini).