Nói một cách chính xác, thuật ngữ "các thủ tục được lưu trữ" chỉ đến các thủ tục SQL trong Postgres, được giới thiệu với Postgres 11. Liên quan:
Ngoài ra còn có các chức năng , làm gần như nhưng không hoàn toàn giống nhau, và những chức năng đã có từ đầu.
Chức năng với LANGUAGE sql
cơ bản hỗ trợ file batch với các lệnh đơn giản SQL trong một wrapper chức năng (và do đó nguyên tử, luôn luôn chạy bên trong một đơn giao dịch) chấp nhận các thông số. Tất cả các câu lệnh trong một hàm SQL được lập kế hoạch cùng một lúc , khác biệt một cách tinh tế so với việc thực hiện một câu lệnh khác và có thể ảnh hưởng đến thứ tự thực hiện các khóa.
Đối với bất cứ điều gì hơn, ngôn ngữ trưởng thành nhất là PL / pgSQL ( LANGUAGE plpgsql
). Nó hoạt động tốt và đã được cải thiện với mỗi bản phát hành trong thập kỷ qua, nhưng nó phục vụ tốt nhất như keo cho các lệnh SQL. Nó không có nghĩa là cho các tính toán nặng nề (ngoài các lệnh SQL).
Các hàm PL / pgSQL thực thi các truy vấn như các câu lệnh đã chuẩn bị . Việc sử dụng lại các gói truy vấn được lưu trong bộ nhớ cache sẽ cắt giảm một số chi phí lập kế hoạch và làm cho chúng nhanh hơn một chút so với các câu lệnh SQL tương đương, có thể là một hiệu ứng đáng chú ý tùy thuộc vào hoàn cảnh. Nó cũng có thể có tác dụng phụ như trong câu hỏi liên quan này:
Điều này mang những ưu điểm và nhược điểm của các tuyên bố đã chuẩn bị - như được thảo luận trong hướng dẫn . Đối với các truy vấn trên các bảng có phân phối dữ liệu không thường xuyên và các tham số khác nhau, SQL động có EXECUTE
thể hoạt động tốt hơn khi mức tăng từ kế hoạch thực hiện được tối ưu hóa cho (các) tham số đã cho vượt xa chi phí lập kế hoạch lại.
Vì các kế hoạch thực hiện chung của Postgres 9.2 vẫn được lưu trong bộ nhớ cache cho phiên, nhưng, trích dẫn hướng dẫn :
Điều này xảy ra ngay lập tức cho các báo cáo chuẩn bị không có tham số; mặt khác, nó chỉ xảy ra sau năm lần thực hiện trở lên tạo ra các kế hoạch mà chi phí trung bình ước tính (bao gồm cả chi phí kế hoạch) đắt hơn so với ước tính chi phí kế hoạch chung.
Chúng tôi nhận được tốt nhất của cả hai thế giới hầu hết thời gian (ít hơn một số chi phí bổ sung) mà không (ab) sử dụng EXECUTE
. Chi tiết về những gì mới trong PostgreSQL 9.2 của PostgreSQL Wiki .
Postgres 12 giới thiệu biến máy chủplan_cache_mode
bổ sung để buộc các gói chung hoặc tùy chỉnh. Đối với trường hợp đặc biệt, sử dụng cẩn thận.
Bạn có thể thắng lớn với các chức năng phía máy chủ ngăn các chuyến đi khứ hồi bổ sung đến máy chủ cơ sở dữ liệu từ ứng dụng của bạn. Yêu cầu máy chủ thực thi càng nhiều càng tốt cùng một lúc và chỉ trả về một kết quả được xác định rõ.
Tránh lồng các hàm phức tạp, đặc biệt là các hàm bảng ( RETURNING SETOF record
hoặc TABLE (...)
). Các hàm là các hộp đen đóng vai trò là rào cản tối ưu hóa cho trình hoạch định truy vấn. Chúng được tối ưu hóa một cách riêng biệt, không phải trong bối cảnh của truy vấn bên ngoài, điều này làm cho việc lập kế hoạch đơn giản hơn, nhưng có thể dẫn đến các kế hoạch ít hơn hoàn hảo. Ngoài ra, chi phí và kích thước kết quả của các chức năng không thể được dự đoán một cách đáng tin cậy.
Các ngoại lệ cho quy tắc này là các hàm SQL đơn giản ( LANGUAGE sql
), mà có thể được "inlined" - nếu một số điều kiện tiên quyết được đáp ứng . Đọc thêm về cách trình lập kế hoạch truy vấn hoạt động trong bản trình bày này của Neil Conway (công cụ nâng cao).
Trong PostgreSQL, một chức năng luôn tự động chạy trong một giao dịch . Tất cả đều thành công hoặc không có gì. Nếu một ngoại lệ xảy ra, mọi thứ sẽ được khôi phục. Nhưng có xử lý lỗi ...
Đó cũng là lý do tại sao các chức năng không chính xác là "thủ tục được lưu trữ" (mặc dù thuật ngữ đó đôi khi được sử dụng, gây hiểu nhầm). Một số lệnh như VACUUM
, CREATE INDEX CONCURRENTLY
hoặc CREATE DATABASE
không thể chạy bên trong khối giao dịch, vì vậy chúng không được phép trong các chức năng. (Tuy nhiên, trong các thủ tục SQL, kể từ Postgres 11. Điều đó có thể được thêm vào sau.)
Tôi đã viết hàng ngàn chức năng plpgsql trong những năm qua.