user
Trong khi viết lại hàm của bạn, tôi nhận ra rằng bạn đã thêm bí danh cột ở đây:
SELECT
...
auth_user.email AS user,
customers.name AS customer,
.. mà sẽ không làm gì cả để bắt đầu, vì những bí danh đó ẩn bên ngoài hàm và không được tham chiếu bên trong hàm. Vì vậy, họ sẽ bị bỏ qua. Đối với mục đích tài liệu, tốt hơn hãy sử dụng một bình luận.
Nhưng nó cũng làm cho truy vấn của bạn không hợp lệ , bởi vì user
là một từ dành riêng hoàn toàn và không thể được sử dụng làm bí danh cột trừ khi được trích dẫn kép.
Thật kỳ lạ, trong các thử nghiệm của tôi, chức năng này dường như hoạt động với bí danh không hợp lệ. Có lẽ vì nó bị bỏ qua (?). Nhưng tôi không chắc điều này không có tác dụng phụ.
Hàm của bạn được viết lại (nếu không thì tương đương):
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;
Rõ ràng, STABLE
từ khóa đã thay đổi kết quả. Tính biến động của chức năng không phải là một vấn đề trong tình huống thử nghiệm mà bạn mô tả. Cài đặt này thường không mang lại lợi nhuận cho một lệnh gọi hàm riêng lẻ. Đọc chi tiết trong sách hướng dẫn. Ngoài ra, EXPLAIN
tiêu chuẩn không hiển thị kế hoạch truy vấn cho những gì đang diễn ra bên trong chức năng. Bạn có thể sử dụng mô-đun bổ sung tự động giải thích vì điều đó:
- Kế hoạch truy vấn postgres của một lời gọi UDF được viết bằng pgpsql
Bạn có một phân phối dữ liệu rất kỳ lạ :
Bảng auth_web_events có 100000000 bản ghi, auth_user-> 2 bản ghi, khách hàng-> 1 bản ghi
Vì bạn không xác định khác, nên hàm giả định ước tính là 1000 hàng được trả lại. Nhưng thực tế hàm của bạn chỉ trả về 2 hàng . Nếu tất cả các lệnh gọi của bạn chỉ trả về (gần) 2 hàng, chỉ cần khai báo điều đó với ROWS 2
được thêm vào . Có thể thay đổi kế hoạch truy vấn cho VOLATILE
cả biến thể (ngay cả khi STABLE
dù sao cũng là sự lựa chọn đúng đắn ở đây).