আসুন এমন একটি ফাংশন তৈরি করুন যার পার্শ্ব প্রতিক্রিয়া রয়েছে যাতে আমরা দেখতে পাই যে এটি কতবার সম্পাদিত হয়:
CREATE OR REPLACE FUNCTION test.this_here(val integer)
RETURNS numeric
LANGUAGE plpgsql
AS $function$
BEGIN
RAISE WARNING 'I am called with %', val;
RETURN sqrt(val);
END;
$function$;
এবং তারপরে আপনার মতো করে কল করুন:
SELECT this_here(i) FROM generate_series(1,10) AS t(i) WHERE this_here(i) < 2;
WARNING: I am called with 1
WARNING: I am called with 1
WARNING: I am called with 2
WARNING: I am called with 2
WARNING: I am called with 3
WARNING: I am called with 3
WARNING: I am called with 4
WARNING: I am called with 5
WARNING: I am called with 6
WARNING: I am called with 7
WARNING: I am called with 8
WARNING: I am called with 9
WARNING: I am called with 10
this_here
──────────────────
1
1.4142135623731
1.73205080756888
(3 rows)
আপনি দেখতে পাচ্ছেন, ফাংশনটি কমপক্ষে একবার কল করা হয় ( WHERE
ক্লজ থেকে ), এবং শর্তটি সত্য হলে, আরও একবার আউটপুট উত্পাদন করতে।
দ্বিতীয় মৃত্যুদণ্ড এড়াতে, আপনি এডগার এর পরামর্শ অনুযায়ী যা করতে পারেন - যথা কোয়েরিটি মোড়ানো এবং ফলাফল সেটটি ফিল্টার করুন:
SELECT *
FROM (SELECT this_here(i) AS val FROM generate_series(1,10) AS t(i)) x
WHERE x.val < 2;
WARNING: I am called with 1
... every value only once ...
WARNING: I am called with 10
এটি কীভাবে কাজ করে তা পরীক্ষা করার জন্য, কেউ সেখানে গিয়ে pg_stat_user_functions
চেক করতে পারে calls
(প্রদত্ত সমস্ত track_functions
কিছু সেট করা আছে)।
আসুন এমন কিছু দিয়ে চেষ্টা করুন যার কোনও পার্শ্ব প্রতিক্রিয়া নেই:
CREATE OR REPLACE FUNCTION test.simple(val numeric)
RETURNS numeric
LANGUAGE sql
AS $function$
SELECT sqrt(val);
$function$;
SELECT simple(i) AS v
FROM generate_series(1,10) AS t(i)
WHERE simple(i) < 2;
-- output omitted
SELECT * FROM pg_stat_user_functions WHERE funcname = 'simple';
-- 0 rows
simple()
তাই এটি করা যেতে পারে আসলে খুব সহজ inlined , সুতরাং এটি দৃশ্য মনে হচ্ছে না। আসুন এটি অন-অন্তর্ভুক্তযোগ্য:
CREATE OR REPLACE FUNCTION test.other_one(val numeric)
RETURNS numeric
LANGUAGE sql
AS $function$
SELECT 1; -- to prevent inlining
SELECT sqrt(val);
$function$;
SELECT other_one(i) AS v
FROM generate_series(1,10) AS t(i)
WHERE other_one(i) < 2;
SELECT * FROM pg_stat_user_functions ;
funcid │ schemaname │ funcname │ calls │ total_time │ self_time
────────┼────────────┼───────────┼───────┼────────────┼───────────
124311 │ test │ other_one │ 13 │ 0.218 │ 0.218
SELECT *
FROM (SELECT other_one(i) AS v FROM generate_series(1,10) AS t(i)) x
WHERE v < 2;
SELECT * FROM pg_stat_user_functions ;
funcid │ schemaname │ funcname │ calls │ total_time │ self_time
────────┼────────────┼───────────┼───────┼────────────┼───────────
124311 │ test │ other_one │ 23 │ 0.293 │ 0.293
যেমনটি দেখা যাচ্ছে, ছবিটি পাশাপাশি বা পার্শ্ব প্রতিক্রিয়া ছাড়াই একই।
পরিবর্তন other_one()
করার জন্য IMMUTABLE
, পরিবর্তন আচরণ (হয়তো এটি আশ্চর্যজনক) খারাপ হিসেবে এটি উভয় ক্যোয়ারিগুলিতে 13 বার ডাকা হবে।
STABLE
/IMMUTABLE
বাVOLATILE
?