Khái niệm nó là lười biếng:
Giống như một biểu thức CASE, COLALESCE chỉ đánh giá các đối số cần thiết để xác định kết quả; có nghĩa là, các đối số ở bên phải của đối số không null đầu tiên không được đánh giá.
https://www.postgresql.org/docs/9.6/static/functions-conditional.html
Tuy nhiên, nếu biểu thức bên phải là không bị tổn hại sau đó nó nên không có sự khác biệt cho dù đó là lười biếng hay không, vì vậy trong trường hợp này nó sẽ cho phép đối với các kế hoạch truy vấn háo hức đánh giá đối số bên phải nếu nó ổn định hoặc không thay đổi, nếu điều này có vẻ là một tối ưu hóa hợp lý.
Một trường hợp rõ ràng là với SELECT COALESCE(a, b) FROM table
nó sẽ có khả năng lấy lại a
và b
lĩnh vực của tất cả các hàng chứ không phải lấy a
và sau đó lấy b
nếu cần thiết.
Cách duy nhất để có bất kỳ hiệu ứng quan sát nào ở đây là nếu bạn đã viết một hàm dễ bay hơi và cố ý gắn nhãn sai nó là stable
hoặc immutable
. Sau đó, nó sẽ là có thể để được đánh giá nếu ở bên phải của một coalesce
trong đó tay trái không phải là rỗng. (Sẽ có thể cho một hàm thực sự ổn định, nhưng nếu nó ổn định nó sẽ không có tác dụng phụ, và nếu nó không có tác dụng phụ cho dù nó xảy ra hay không sẽ không thể quan sát được).
Given:
CREATE OR REPLACE FUNCTION immutable_func(arg integer)
RETURNS integer
AS $BODY$
BEGIN
RAISE NOTICE 'Immutable function called with %', arg;
RETURN arg;
END;
$BODY$ LANGUAGE plpgsql IMMUTABLE;
WITH data AS
(
SELECT 10 AS num
UNION ALL SELECT 5
UNION ALL SELECT 20
)
select coalesce(num, immutable_func(2))
from data
Các kế hoạch đều biết rằng nó sẽ có kết quả tương tự cho immutable_func(2)
cho mỗi hàng và gọi đó là một lần duy nhất cho toàn bộ truy vấn, cho chúng ta thông điệp Immutable function called with 2
. Vì vậy, nó đã thực sự được đánh giá mặc dù nó không nằm trong quy tắc của "đối số ở bên phải của đối số không null đầu tiên không được đánh giá". Việc trả tiền là trong trường hợp (hợp lý để mong đợi) của nhiều null num
nó sẽ vẫn chỉ chạy một lần.
Điều này chống lại chữ của hành vi được ghi nhận là tốt, bởi vì chúng tôi đã nói với nó rằng việc tối ưu hóa như vậy là hợp lệ. Nếu điều này gây ra sự cố, lỗi sẽ có chức năng được đánh dấu là IMMUTABLE
không phải trong đánh giá háo hức.
Nó cũng có thể là một phần. Với SELECT COALESCE(a, Some_Func(b)) FROM table
nó sẽ không được đánh giá Some_Func(b)
háo hức, nhưng nó sẽ được truy xuất b
để có thể làm như vậy.
Bất cứ khi nào nó thực sự ảnh hưởng đến hành vi quan sát (không gian lận), quy tắc được tuân theo.
Câu hỏi hay. Tôi muốn nói: kiểm tra kế hoạch. – wildplasser