2017-02-23 9 views
6

अगर मैं इस तरह एक प्रश्न है:पोस्टग्रेज़ कोलेज़ आलसी है?

SELECT COALESCE(
    (SELECT value FROM precomputed WHERE ...), 
    alwaysComputeValue(...) 
); 

दूसरी अभिव्यक्ति का मूल्यांकन किया जा सकता है? क्या यह निष्पादन योजनाकार पर निर्भर करता है या यह स्वतंत्र है?

+4

अच्छा सवाल। मैं कहूंगा: योजना की जांच करें। – wildplasser

उत्तर

4

वैचारिक यह आलसी है:

एक मामला अभिव्यक्ति की तरह

, संगठित केवल तर्क है कि परिणाम निर्धारित करने के लिए आवश्यक हैं का मूल्यांकन करता है; यानी, पहले गैर-शून्य तर्क के अधिकार के तर्कों का मूल्यांकन नहीं किया जाता है।

https://www.postgresql.org/docs/9.6/static/functions-conditional.html

हालांकि, अगर सही करने के लिए अभिव्यक्ति अस्थिर नहीं है तो यह कोई फर्क नहीं है कि क्या यह आलसी या नहीं था, इसलिए इस तरह के एक मामले में यह क्वेरी योजनाकार के लिए स्वीकार्य होगा बनाना चाहिए बेसब्री अगर यह स्थिर या अपरिवर्तनीय था, तो दाएं हाथ के तर्क का मूल्यांकन करें, अगर यह एक समझदार अनुकूलन प्रतीत होता है।

एक स्पष्ट मामला है कि SELECT COALESCE(a, b) FROM table साथ यह संभावना नहीं बल्कि a पुन: प्राप्त करने और उसके बाद b पुन: प्राप्त करने यदि आवश्यक हो तो से सभी पंक्तियों के a और b क्षेत्रों को पुनः प्राप्त होगा।

यहां कोई अवलोकन करने योग्य प्रभाव होने का एकमात्र तरीका यह है कि यदि आपने अस्थिर कार्य लिखा है और जानबूझकर इसे stable या immutable के रूप में गलत लेबल किया है। तो यह संभव होगा यदि इसका मूल्यांकन coalesce के दाएं हाथ पर किया गया था जहां बाएं हाथ शून्य नहीं था। (यह एक ऐसे फ़ंक्शन के लिए संभव होगा जो वास्तव में निश्चित रूप से स्थिर भी था, लेकिन यदि यह स्थिर था तो इसका कोई दुष्प्रभाव नहीं होगा, और यदि इसका कोई दुष्प्रभाव नहीं था या नहीं, तो यह देखा जा सकता है या नहीं)।

को देखते हुए:

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 

योजनाकार जानता है कि यह हर पंक्ति के लिए immutable_func(2) के लिए एक ही परिणाम होगा और पूरे क्वेरी के लिए एक ही समय में यह कहता है, हमें संदेश Immutable function called with 2 दे रही है। तो इसका मूल्यांकन वास्तव में किया गया है, भले ही यह "गैर-शून्य तर्क के अधिकार के तर्कों का मूल्यांकन नहीं किया गया है" के नियम के भीतर नहीं है। पे-ऑफ यह है कि कई शून्य num के मामले (उचित उम्मीद करने के लिए) में यह अभी भी एक बार चलाएगा।

यह दस्तावेज व्यवहार के पत्र के खिलाफ है ठीक है, क्योंकि हमने यह बताया है कि ऐसा अनुकूलन मान्य है। यदि इससे कोई समस्या उत्पन्न हुई तो कार्य को उत्सुक मूल्यांकन में IMMUTABLE के रूप में चिह्नित करने में नहीं होगा।

यह भी अंश-मार्ग हो सकता है। SELECT COALESCE(a, Some_Func(b)) FROM table के साथ यह उत्सुकता से Some_Func(b) का मूल्यांकन नहीं करेगा, लेकिन ऐसा करने में सक्षम होने के लिए b पुनर्प्राप्त किया जाएगा।

किसी भी समय यह वास्तव में (गैर-धोखाधड़ी) देखने योग्य व्यवहार पर असर डालता है, नियम का पालन किया जाता है।

+0

वाह, इतना लंबा जवाब, लेकिन .. मुझे पता है कि इसका मूल्यांकन * सिद्धांत में किया जा सकता है * यदि मैं अपरिवर्तनीय या स्थिर कार्य को चिह्नित करता हूं और इसे योजनाकार के लिए कम लागत निर्धारित करता हूं, * लेकिन * क्या यह वास्तव में * हो सकता है? :-) – langpavel

+0

हां यह कर सकता है। जवाब अपडेट करेंगे। –

4

the documentation से:

एक मामला अभिव्यक्ति की तरह, COALESCE केवल तर्क है कि परिणाम निर्धारित करने के लिए आवश्यक हैं का मूल्यांकन करता है; यानी, पहले गैर-शून्य तर्क के अधिकार के तर्कों का मूल्यांकन नहीं किया जाता है।

संबंधित मुद्दे