Sqlserver
 sql >> डेटाबेस >  >> RDS >> Sqlserver

SQL सर्वर में COALESCE फ़ंक्शन पर 5 ज्वलंत प्रश्नों के शीर्ष उत्तर

SQL में COALESCE फ़ंक्शन कितना अच्छा है?

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

आज, आपको SQL COALESCE व्यंजक के बारे में सर्वाधिक पूछे जाने वाले पाँच प्रश्नों के उत्तर मिलेंगे। इनमें से एक पर बार-बार बहस हो रही है।

क्या हम शुरू करें?

SQL में COALESCE फ़ंक्शन का उपयोग क्या है?

इसका उत्तर 2 शब्दों में दिया जा सकता है:नल को संभालना

शून्य मूल्यों का शून्य है। दूसरे शब्दों में, अज्ञात। यह एक खाली स्ट्रिंग या शून्य संख्या से अलग है। नल को संभालने के लिए अभिव्यक्तियों और कार्यों के उपयोग की आवश्यकता होती है। उनमें से एक COALESCE है।

मेरा मतलब समझने के लिए, नीचे दिए गए कथन देखें:

DECLARE @number INT

SELECT @number + 33587

क्या यह ठीक चलेगा? यह होगा।

क्या यहाँ कोई समस्या है? इस समय कोई नहीं।

लेकिन कथनों का परिणाम NULL होगा क्योंकि किसी संख्या में शून्य जोड़ना NULL के बराबर होता है।

यदि आपके सभी प्रश्न केवल इस स्तर तक आते हैं, तो आप पढ़ना बंद कर सकते हैं। लेकिन निश्चित रूप से, वे नहीं हैं। हमें इस प्रकार के कोड को बनाने से अधिक के लिए भुगतान किया जा रहा है।

अब, थोड़ा 'आपदा' जोड़ें:

DECLARE @number INT

SET @number = @number + 33587

UPDATE myTable
set col1 = @number   -- Surprise! col1 is NOT NULLABLE
where ID = 1

PRINT 'Success!'

UPDATE स्टेटमेंट तक पहुंचने पर उपरोक्त कोड का निष्पादन डेड-एंड पर होगा। यह 'सफलता!' प्रिंट नहीं करेगा क्योंकि आप एक गैर-शून्य कॉलम पर एक शून्य नहीं डाल सकते हैं। क्या यह कथन स्पष्ट बोलता है कि हमें नल को संभालने की आवश्यकता क्यों है?

आइए सुरक्षा जाल जोड़ने के लिए कोड बदलें:

DECLARE @number INT

SET @number = COALESCE(@number,0) + 33587     -- our safety net. Thanks to COALESCE.

UPDATE myTable
set col1 = @number               -- Disaster averted!
where ID = 1

PRINT 'Success!'

COALESCE शून्य मान को शून्य में बदल देगा, और योग शून्य नहीं होगा।

सबक है, COALESCE नल के खिलाफ सुरक्षा जाल में से एक है। इससे भी बेहतर, अपने SQL कोड में नल को ठीक से संभालना आपके सिरदर्द को कम करता है और आपको जल्दी घर जाने देता है। यह पक्का है।

अब आप समझ गए हैं कि मैं अपनी टीम में किसी ऐसे व्यक्ति को क्यों चाहता हूं जो नल को संभालने में मेहनती हो।

SQL COALESCE के उपयोग में अधिक व्यावहारिक उदाहरण

आइए अधिक व्यावहारिक उदाहरण देखें।

मान लीजिए आप ऐसे क्षेत्र में रहते हैं जहां कुछ लोगों के मध्य नाम हैं, लेकिन अन्य नहीं हैं। आप पहले नाम, मध्य नाम और अंतिम नाम से पूरा नाम कैसे बनाएंगे, बिना किसी जाल में पड़े?

COALESCE का उपयोग करके यहां एक संभावित समाधान दिया गया है:

USE AdventureWorks
GO

SELECT
p.LastName + ', ' + p.FirstName + ' ' + COALESCE(p.MiddleName + ' ','') AS FullName
FROM Person.Person p

एक अन्य उदाहरण:मान लीजिए कि आप एक ऐसी कंपनी में कर्मचारी हैं, जहां प्रत्येक कर्मचारी के लिए सकल वेतन की गणना अलग-अलग तरीके से की जाती है। उनमें से कुछ के लिए, प्रति घंटा की दरें हैं। दूसरों को साप्ताहिक या मासिक दरों पर भुगतान मिलता है।

COALESCE का उपयोग करके क्वेरी समाधान के साथ तालिका का नमूना यहां दिया गया है:

-- STEP 1: Create the table
CREATE TABLE EmployeeWages (
    employee_id INT PRIMARY KEY,
    hourly_rate SMALLMONEY,
    weekly_rate SMALLMONEY,
    monthly_rate MONEY,
    CHECK(
        hourly_rate IS NOT NULL OR
        weekly_rate IS NOT NULL OR
        monthly_rate IS NOT NULL)
);

-- STEP 2: Insert data
INSERT INTO
    EmployeeWages(
        employee_id,
        hourly_rate,
        weekly_rate,
        monthly_rate
    )
VALUES
    (1,60, NULL,NULL),
    (2,40, NULL,NULL),
    (3,NULL, 1000,NULL),
    (4,NULL, NULL,7000),
    (5,NULL, NULL,5000);

-- STEP 3: Query the monthly salary.
SELECT
    employee_id,
    COALESCE(
        hourly_rate*22.00*8.00,
        weekly_rate*4.00,
        monthly_rate
    ) AS monthly_salary
FROM
    EmployeeWages;

तालिका में प्रति कर्मचारी आईडी अलग-अलग वेतन मोड हैं। क्वेरी के लिए आपको सभी के लिए मासिक वेतन देना होगा।

यह वह जगह है जहां COALESCE चमकेगा:यह मूल्यों की एक सूची स्वीकार करता है, और इसमें कई आइटम हो सकते हैं। COALESCE पहले वाले को चुनेगा जो शून्य नहीं है:

साफ, है ना?

COALESCE SQL में कैसे कार्य करता है?

COALESCE की परिभाषा एक ऐसा व्यंजक है जो मानों की सूची से पहला गैर-शून्य मान लौटाता है। COALESCE सिंटैक्स है:

COALESCE (अभिव्यक्ति [ ,…n ] )

मजदूरी के लिए विभिन्न भुगतान विधियों के साथ हमारा पिछला उदाहरण इसे दर्शाता है।

हूड के तहत क्या है

हुड के तहत, SQL में COALESCE फ़ंक्शन लंबे समय तक CASE अभिव्यक्ति के लिए एक चीनी-लेपित अभिव्यक्ति है। यह एक समान CASE टाइप करने की आवश्यकता को समाप्त करता है, जो मेरे जैसे आलसी टाइपिस्ट के लिए लंबा (और थका देने वाला) है। परिणाम वही होगा।

क्या हम इसे साबित कर सकते हैं? हां! एक के लिए, Microsoft इसे स्वीकार करता है।

लेकिन हमारे लिए अच्छा है, Microsoft ने इसे निष्पादन योजना में शामिल किया। इस प्रकार, हम जानते हैं कि क्या हो रहा है।

आइए मजदूरी के साथ पिछले उदाहरण का उपयोग करके इसे आजमाएं। लेकिन इससे पहले कि आप नीचे दी गई क्वेरी को फिर से चलाएँ, वास्तविक निष्पादन योजना शामिल करें चालू करें या बस CTRL-M press दबाएं ।

SELECT
    employee_id,
    COALESCE(
        hourly_rate * 22.00 * 8.00,
        weekly_rate * 4.00,
        monthly_rate
    ) AS monthly_salary
FROM
    EmployeeWages;

निष्पादन योजना . पर क्लिक करें परिणामों में टैब। यह सरल दिखता है, लेकिन हमारा छिपा हुआ रत्न गणना स्केलर . में निहित है नोड. जब आप उस पर माउस घुमाते हैं, तो आपको Expr1002 . नाम का एक एक्सप्रेशन दिखाई देता है (चित्र 2)। यह क्या हो सकता है?

आइए गहरी खुदाई करें। उस पर राइट-क्लिक करें और निष्पादन योजना XML दिखाएं चुनें . एक नई विंडो खुलकर आएगी। नीचे चित्र 3 पर एक नज़र डालें:

आपका केस स्टेटमेंट है। पठनीयता के लिए पूरी चीज़ को स्वरूपित और इंडेंट किया गया है:

CASE WHEN CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[hourly_rate],0)
                                            *(22.00)*(8.00) IS NOT NULL
     THEN CONVERT_IMPLICIT(numeric(23,8),CONVERT_IMPLICIT(numeric(10,4),
                       [TestDatabase].[dbo].[EmployeeWages].[hourly_rate],0)*(22.00)*(8.00),0)
     ELSE CASE WHEN    
          CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)
                                            *(4.00) IS NOT NULL
          THEN CONVERT_IMPLICIT(numeric(23,8),CONVERT_IMPLICIT(numeric(10,4),                                                         
                       [TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)*(4.00),0)
          ELSE CONVERT_IMPLICIT(numeric(23,8),[TestDatabase].[dbo].[EmployeeWages].[monthly_rate],0)
          END
END

इसकी तुलना में यह काफी लंबा है

COALESCE(
        hourly_rate * 22.00 * 8.00,
        weekly_rate * 4.00,
        monthly_rate
        )

COALESCE के साथ हमारी क्वेरी के साथ SQL सर्वर ने यही किया। सब कुछ पहला मान प्राप्त करने के लिए है जो मानों की सूची में शून्य नहीं है।

क्या यह छोटा हो सकता है?

मैं जानता हूं तुम क्या सोच्र रहे हो। यदि SQL सर्वर क्वेरी प्रोसेसिंग के दौरान ऐसा करता है, तो COALESCE धीमा होना चाहिए। CONVERT_IMPLICIT के कई प्रकटन का उल्लेख नहीं है। क्या आप इसके बजाय विकल्पों का उपयोग करेंगे?

एक के लिए, आप स्वयं एक छोटा CASE कथन टाइप कर सकते हैं। या, आप ISNULL का उपयोग कर सकते हैं। उस पर और बाद में। धीमे होने की बात करते हुए, मैंने इस पोस्ट के समाप्त होने से पहले इसे कवर कर लिया था।

SQL में COALESCE और ISNULL में क्या अंतर हैं?

COALESCE के विकल्पों में से एक ISNULL है। COALESCE का 2 मानों के साथ उपयोग करने से यह ISNULL के समान हो जाता है। कम से कम, परिणाम समान दिखते हैं। फिर भी, उल्लेखनीय अंतर हैं। आप COALESCE या ISNULL का उपयोग करेंगे या नहीं यह तय करने के लिए आप इसे एक गाइड के रूप में उपयोग कर सकते हैं।

(1) ISNULL 2 तर्क स्वीकार करता है। COALESCE तर्कों की सूची स्वीकार करता है

यह सबसे स्पष्ट अंतर है। वाक्य रचना से, यह निश्चित रूप से अलग है।

ISNULL ( check_expression , replace_value )
COALESCE (अभिव्यक्ति [ ,…n ] )

जब आप 2 तर्कों के साथ दोनों का उपयोग करते हैं, तो परिणाम समान होते हैं। नीचे दिए गए 2 कथनों का परिणाम 1 होगा:

SELECT ISNULL(NULL, 1)
SELECT COALESCE(NULL, 1)

हालांकि परिणाम समान हैं, उनका मतलब अलग है:

  • ISNULL(NULL, 1) 1 लौटा, क्योंकि पहला तर्क NULL है।
  • COALESCE(NULL, 1) 1 लौटा, क्योंकि 1 सूची में पहला गैर-शून्य मान है

(2) COALESCE SQL-92 मानक है

ये सही है। तुम उसे देख सकते हो। उदाहरण के लिए, यदि आप अपने SQL कोड को SQL सर्वर से MySQL में पोर्ट करना चाहते हैं, तो COALESCE वही कार्य करेगा। चित्र 4 देखें और चित्र 1 से परिणाम की तुलना करें:

हालाँकि, यदि आप SQL सर्वर के सिंटैक्स का उपयोग करते हैं, तो MySQL में ISNULL का उपयोग करने से एक त्रुटि उत्पन्न होगी।

उदाहरण के लिए, SQL सर्वर प्रबंधन स्टूडियो और MySQL कार्यक्षेत्र में निम्नलिखित चलाएँ:

SELECT ISNULL(null,1)

क्या हुआ? SQL सर्वर में, आउटपुट 1 है। लेकिन MySQL में, आउटपुट एक त्रुटि है:

06:36:52 ISNULL (null,1) एरर कोड चुनें:1582। नेटिव फंक्शन 'ISNULL' पर कॉल में गलत पैरामीटर काउंट

बात यह है कि, MySQL में ISNULL 1 तर्क स्वीकार करता है और तर्क शून्य होने पर 1 लौटाता है। अन्यथा, यह 0 लौटाता है।

(3) COALESCE में 2 नल पास करना एक त्रुटि को ट्रिगर करता है। ISNULL के साथ यह ठीक है

यह एक त्रुटि ट्रिगर करेगा:

SELECT COALESCE(NULL, NULL)

त्रुटि यह है:'COALESCE के तर्कों में से कम से कम एक ऐसा व्यंजक होना चाहिए जो NULL स्थिरांक न हो।'

यह ठीक रहेगा:

SELECT ISNULL(NULL, NULL)

COALESCE कोड को नीचे कुछ इसी तरह बदलने से कोई त्रुटि ट्रिगर नहीं होगी:

DECLARE @value INT = NULL
SELECT COALESCE(@value,null)

ऐसा इसलिए हुआ क्योंकि @value शून्य स्थिरांक नहीं है।

(4) SQL COALESCE को CASE में कनवर्ट किया जाता है। ISNULL ISNULL रहता है

हमने इसे ‘COALESCE SQL में कैसे काम करता है?’ . में देखा है खंड। यहां, आइए एक और उदाहरण देखें:

SELECT
P.LastName + ', ' + P.FirstName + ' ' + COALESCE(P.MiddleName + ' ','') AS FullName
FROM Person.Person p

निष्पादन योजना XML . का निरीक्षण स्केलर ऑपरेटर के लिए रूपांतरण को CASE में प्रकट करता है:

 [AdventureWorks].[Person].[Person].[LastName] as [p].[LastName]+N', '
+[AdventureWorks].[Person].[Person].[FirstName] as [p].[FirstName]+N' '
+CASE WHEN ([AdventureWorks].[Person].[Person].[MiddleName] as [p].[MiddleName]+N' ') IS NOT NULL
      THEN [AdventureWorks].[Person].[Person].[MiddleName] as [p].[MiddleName]+N' '
      ELSE N''
 END

अब, ISNULL का उपयोग करके एक समान क्वेरी चलाएँ:

SELECT
P.LastName + ', ' + P.FirstName + ' ' + ISNULL(P.MiddleName + ' ','') AS FullName
FROM Person.Person p

फिर, निष्पादन योजना XML का निरीक्षण करें अदिश संचालिका के लिए:

 [AdventureWorks].[Person].[Person].[LastName] as [p].[LastName]+N', '
+[AdventureWorks].[Person].[Person].[FirstName] as [p].[FirstName]+N' '
+isnull([AdventureWorks].[Person].[Person].[MiddleName] as [p].[MiddleName]+N' ',N'')

ISNULL अभी भी ISNULL है।

(5) परिणामी अभिव्यक्ति का डेटा प्रकार अलग है

परिणामी व्यंजक का डेटा प्रकार निर्धारण COALESCE और ISNULL के बीच भी भिन्न होता है:

  • ISNULL पहले पैरामीटर के डेटा प्रकार का उपयोग करता है।
  • COALESCE उच्चतम प्राथमिकता के साथ मान का डेटा प्रकार लौटाता है।

डेटा प्रकार की प्राथमिकता की सूची के लिए, इस लिंक को देखें।

आइए एक उदाहरण लेते हैं:

SELECT
 employee_id
,COALESCE(CAST(weekly_rate * 4 AS MONEY),0.0000) AS monthly_rate
FROM EmployeeWages

फिर, निष्पादन योजना XML . में CASE में रूपांतरण का निरीक्षण करें :

CASE WHEN CONVERT(money,[TestDatabase].[dbo].[EmployeeWages].[weekly_rate]
                                           *CONVERT_IMPLICIT(smallmoney,[@1],0),0) IS NOT NULL
     THEN CONVERT_IMPLICIT(numeric(19,4), CONVERT(money,[TestDatabase].[dbo].[EmployeeWages].[weekly_rate]
                                           *CONVERT_IMPLICIT(smallmoney,[@1],0),0),0)
     ELSE (0.0000)
END

उपरोक्त CASE व्यंजक में, परिणाम का डेटा प्रकार संख्यात्मक(19,4) होगा।

क्यों? इसकी प्राथमिकता पैसे . से अधिक है और छोटा पैसा भले ही आप इसे पैसे . में कास्ट करें . क्यों संख्यात्मक और नहीं पैसा ? निरंतर 0.0000 के कारण।

यदि आप सोच रहे हैं कि @1 क्या है, तो निष्पादन योजना XML जवाब है। यह स्थिरांक 4 है।

<ParameterList>
 <ColumnReference Column="@1" ParameterDataType="int" ParameterCompiledValue="(4)"  
       ParameterRuntimeValue="(4)" />
</ParameterList>

आइए इसे ISNULL के साथ आज़माएँ:

SELECT
 employee_id
,ISNULL(CAST(weekly_rate * 4 AS MONEY),0.0000) AS monthly_rate
FROM EmployeeWages

फिर से, स्केलर ऑपरेटर की तलाश करें स्केलरस्ट्रिंग :

ISNULL(CONVERT(MONEY,[TestDatabase].[dbo].[EmployeeWages].[weekly_rate]*($4.0000),0),($0.0000))

अंत में, परिणामी अभिव्यक्ति का डेटा प्रकार पैसा होगा . यह पहले तर्क का डेटा प्रकार है।

डेटा वरीयता को बेहतर कैसे करें

आप अपने कोड में कुछ बदलाव जोड़कर डेटा प्राथमिकता को 'आउटमार्ट' कर सकते हैं। इससे पहले, परिणाम में संख्यात्मक . था डेटा प्रकार। यदि आप चाहते हैं कि परिणाम पैसा हो डेटा प्रकार और CONVERT_IMPLICIT से छुटकारा पाएं, निम्न कार्य करें:

SELECT
 employee_id
,COALESCE(CAST(weekly_rate AS MONEY) * ($4.0000),($0.0000)) AS monthly_rate
FROM EmployeeWages

क्या आपने ($4.000) और ($0.0000) स्थिरांक देखा? वे हैं पैसा स्थिरांक आगे क्या होता है निष्पादन योजना XML . में प्रकट होता है स्केलरस्ट्रिंग :

CASE WHEN CONVERT(money,[TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)*($4.0000) IS NOT NULL 
     THEN CONVERT(money,[TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)*($4.0000) 
     ELSE ($0.0000) 
END

यह ज़्यादा बेहतर है। यह छोटा है, और CONVERT_IMPLICIT चला गया है। और परिणामी डेटा प्रकार पैसा . है ।

(6) परिणामी अभिव्यक्ति की शून्यता अलग है

ISNULL(NULL, 1) और COALESCE(NULL, 1) के समान परिणाम हैं, लेकिन उनके शून्यता मान भिन्न हैं। COALESCE अशक्त है। ISNULL नहीं है। आप इसे परिकलित स्तंभों पर उपयोग करते समय देख सकते हैं।

आइए एक उदाहरण देखें। नीचे दिया गया कथन एक त्रुटि को ट्रिगर करेगा क्योंकि प्राथमिक कुंजी NULL मान स्वीकार नहीं कर सकती है। साथ ही, column2 . के लिए COALESCE व्यंजक की अशक्तता NULL का मूल्यांकन करता है।

CREATE TABLE NullabilityDemo  
(  
  column1 INTEGER NULL,  
  column2 AS COALESCE(column1, 0) PRIMARY KEY,  
  column3 AS ISNULL(column1, 0)  
);

यह कथन सफल होता है क्योंकि ISNULL फ़ंक्शन की शून्यता AS NOT NULL का मूल्यांकन करती है।

CREATE TABLE NullabilityDemo  
(  
  column1 INTEGER NULL,  
  column2 AS COALESCE(column1, 0),  
  column3 AS ISNULL(column1, 0) PRIMARY KEY  
);

(7) ISNULL के वाम तर्क का मूल्यांकन एक बार किया जाता है। यह COALESCE के विपरीत है

पिछले उदाहरण पर फिर से विचार करें:

SELECT
    employee_id,
    COALESCE(
        hourly_rate*22.00*8.00,
        weekly_rate*4.00,
        monthly_rate
    ) AS monthly_salary
FROM
    EmployeeWages;

फिर, ScalarString . का निरीक्षण करें इसके लिए:

CASE WHEN CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[hourly_rate],0)
                                              *(22.00)*(8.00) IS NOT NULL 
     THEN CONVERT_IMPLICIT(numeric(23,8),CONVERT_IMPLICIT(numeric(10,4),
                                              [TestDatabase].[dbo].[EmployeeWages].[hourly_rate],0)
                                              *(22.00)*(8.00),0) 
     ELSE CASE WHEN CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)
                                              *(4.00) IS NOT NULL 
               THEN CONVERT_IMPLICIT(numeric(23,8),CONVERT_IMPLICIT(numeric(10,4),
                                        [TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)*(4.00),0) 
               ELSE CONVERT_IMPLICIT(numeric(23,8),[TestDatabase].[dbo].[EmployeeWages].[monthly_rate],0) 
          END 
END

जब SQL में COALESCE फ़ंक्शन को CASE में कनवर्ट किया जाता है, तो प्रत्येक व्यंजक का दो बार मूल्यांकन किया जाता है (पिछले एक को छोड़कर)। जैसा कि आप ऊपर देख सकते हैं, प्रति घंटा_दर*22.00*8.00 दो बार दिखाई दिया। साप्ताहिक_दर*4.00 . के साथ भी यही बात है . अंतिम अभिव्यक्ति, मासिक_दर , एक बार दिखाई दिया।

चूंकि COALESCE दो बार भावों का मूल्यांकन करेगा, इसलिए प्रदर्शन दंड हो सकता है। इस पर बाद में।

हालांकि, ISNULL समकक्ष देखें:

SELECT
 employee_id,
 ISNULL(hourly_rate * 22.00 * 8.00,ISNULL(weekly_rate * 4.00,monthly_rate)) AS  
                                                       monthly_salary
FROM EmployeeWages

फिर, हम ScalarString . का निरीक्षण करते हैं निष्पादन योजना XML . में :

isnull(CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[hourly_rate],0)*(22.00)*(8.00),
       CONVERT_IMPLICIT(numeric(19,8),
isnull(CONVERT_IMPLICIT(numeric(10,4),[TestDatabase].[dbo].[EmployeeWages].[weekly_rate],0)*(4.00),
CONVERT_IMPLICIT(numeric(14,6),[TestDatabase].[dbo].[EmployeeWages].[monthly_rate],0)),0))

जैसा कि आप ऊपर देख सकते हैं, प्रति घंटा की दर , साप्ताहिक_दर , और मासिक_दर केवल एक बार दिखाई दिया। इसलिए, आपको ISNULL के साथ दो बार भावों का मूल्यांकन किए जाने के बारे में चिंता करने की आवश्यकता नहीं है।

क्या हम COALESCE को WHERE क्लॉज में इस्तेमाल कर सकते हैं?

अवश्य। इसे साबित करने के लिए एक उदाहरण दिखाने से बेहतर कोई तरीका नहीं है।

-- Query all the names in Person table with no middle name

USE AdventureWorks
GO

SELECT
 p.LastName
,p.FirstName
FROM person.Person p
WHERE COALESCE(p.MiddleName,'') = ''

COALESCE एक रिक्त स्ट्रिंग लौटाएगा यदि MiddleName शून्य है। बेशक, परिणाम उत्पन्न करने का एक छोटा तरीका है। लेकिन इससे पता चलता है कि COALESCE WHERE क्लॉज में काम करता है।

कौन सा तेज़ है:COALESCE या ISNULL?

अंत में, हम एक गर्म विषय पर आए हैं:प्रदर्शन!

आपको परीक्षण और तुलना के साथ कई पृष्ठ मिलेंगे, लेकिन टिप्पणियों में COALESCE और ISNULL समर्थकों की लड़ाई होगी। हम उन युद्धों की धूल और धुएँ को साफ़ कर देंगे।

कौन सा तेज़ है:COALESCE या ISNULL? मैं यह कहकर शुरू करता हूं कि इसका उत्तर है:

(ड्रम रोलिंग)

यह निर्भर करता है!

(जबड़ा गिरा)

निराश? मैं इसे एक पल में समझाता हूँ।

सबसे पहले, मैं मानता हूं कि यदि आप बीता हुआ समय अपने मीट्रिक के रूप में उपयोग करते हैं तो दोनों के प्रदर्शन में अंतर प्रतीत होता है। कुछ लोगों ने इस तथ्य का समर्थन किया जब SQL सर्वर COALESCE को CASE कथनों में अनुवादित करता है। इस बीच, ISNULL जस का तस बना रहता है।

अलग-अलग परिणामों के कारण अन्य लोग अलग-अलग तर्क कर सकते हैं। साथ ही, उनके लिए, पलक झपकते ही COALESCE को CASE में कनवर्ट करना हमारी आँखों की तुलना में तेज़ है। जैसा कि इस धागे में बताया गया है, प्रदर्शन अंतर 'छोटा है।' मैं सहमत हूं। यहां एक और लेख है जिसमें कहा गया है कि अंतर 'मामूली है।'

हालाँकि, यहाँ एक बड़ी बात है:क्या हम एक मीट्रिक के रूप में एक छोटे से बीता हुआ समय पर भरोसा कर सकते हैं? वास्तव में क्या मायने रखता है कि क्वेरी में कितना तार्किक पठन है। हम अपने अगले उदाहरणों में यही बताने जा रहे हैं।

(तार्किक पठन के बारे में मेरा अन्य लेख देखें और यह कारक क्यों आपके प्रश्नों को पीछे छोड़ देता है।)

उदाहरण 1

आइए उसी उदाहरण की जांच करें और उनके तार्किक पढ़ने और निष्पादन योजनाओं की तुलना करें। इसे चलाने से पहले, सुनिश्चित करें कि सांख्यिकी IO चालू है और वास्तविक निष्पादन योजना शामिल करें सक्षम है।

SET STATISTICS IO ON

SELECT
P.LastName + ', ' + P.FirstName + ' ' + COALESCE(P.MiddleName + ' ','') AS FullName
FROM Person.Person p

SELECT
P.LastName + ', ' + P.FirstName + ' ' + ISNULL(P.MiddleName + ' ','') AS FullName
FROM Person.Person p

ये हैं तथ्य:

दोनों प्रश्नों के लिए तार्किक पठन समान हैं। दोनों 107*8KB पेज के हैं। यदि हमारे पास एक लाख रिकॉर्ड हैं, तो निश्चित रूप से तार्किक पठन बढ़ेगा। लेकिन दोनों प्रश्नों के लिए तार्किक पठन समान होगा। यदि COALESCE CASE में परिवर्तित हो जाता है तो भी ऐसा ही है:

आइए निष्पादन योजना का निरीक्षण करें। यहां बताया गया है कि हम इसे कैसे करने जा रहे हैं:

  1. COALESCE व्यंजक के साथ पहला चयन कथन निष्पादित करें।
  2. निष्पादन योजना पर क्लिक करें परिणामों में टैब। उस पर राइट-क्लिक करें और निष्पादन योजना को इस रूप में सहेजें select चुनें . और फ़ाइल को नाम दें plan1.sqlplan
  3. आईएसएनयूएलएल फ़ंक्शन के साथ दूसरा चयन कथन निष्पादित करें।
  4. निष्पादन योजना पर क्लिक करें परिणामों में टैब।
  5. इस पर राइट-क्लिक करें और शोप्लान की तुलना करें . चुनें ।
  6. फ़ाइल चुनें plan1.sqlplan . एक नई विंडो दिखाई देगी।

इस तरह हम सभी उदाहरणों के लिए निष्पादन योजना का निरीक्षण करने जा रहे हैं।

अपने पहले उदाहरण पर वापस आते हुए, निष्पादन योजना तुलना देखने के लिए चित्र 6 देखें:

क्या आपने चित्र 6 में इन महत्वपूर्ण बिंदुओं पर ध्यान दिया?

  • 2 योजनाओं के छायांकित भाग (सूचकांक स्कैन) का अर्थ है कि SQL सर्वर ने 2 प्रश्नों के लिए समान संचालन का उपयोग किया है।
  • QueryPlanHash 2 योजनाओं के लिए 0x27CEB4CCE12DA5E7 है, जिसका अर्थ है कि योजना दोनों के लिए समान है।
  • बीते समय के लिए कुछ मिलीसेकंड का अंतर नगण्य है।

टेकअवे

यह सेब की तुलना सेब से करने जैसा है, लेकिन विभिन्न प्रकार के। एक जापान का फ़ूजी सेब है, दूसरा न्यूयॉर्क का लाल सेब है। फिर भी, वे दोनों सेब हैं।

इसी तरह, SQL सर्वर को समान संसाधनों और दोनों प्रश्नों के लिए चुनी गई निष्पादन योजना की आवश्यकता होती है। COALESCE या ISNULL के उपयोग में एकमात्र अंतर है। मामूली अंतर, क्योंकि अंतिम परिणाम वही है।

उदाहरण 2

बड़ा अंतर तब दिखाई देता है जब आप COALESCE और ISNULL दोनों के तर्क के रूप में एक सबक्वेरी का उपयोग करते हैं:

USE AdventureWorks
GO

SELECT COALESCE(
       (SELECT
        SUM(th.ActualCost)
        FROM Production.TransactionHistory th
        WHERE th.ProductID = 967)
       ,0) 

SELECT ISNULL(
       (SELECT
        SUM(th.ActualCost)
        FROM Production.TransactionHistory th
        WHERE th.ProductID = 967)
       ,0)

उपरोक्त कोड का एक ही परिणाम होगा, लेकिन अंदर बहुत अलग है।

आइए तार्किक पठन के साथ शुरू करें:

COALESCE व्यंजक के साथ SELECT कथन में ISNULL का उपयोग करने वाले के तार्किक पठन का दोगुना है।

लेकिन लॉजिकल डबल क्यों पढ़ता है? निष्पादन योजना की तुलना और भी अधिक प्रकट करेगी:

चित्र 8 बताता है कि COALESCE का उपयोग करके तार्किक रीड डबल क्यों हैं। नीचे की योजना में 2 स्ट्रीम एग्रीगेट नोड्स देखें:वे डुप्लिकेट हैं। अगला सवाल यह है कि इसकी नकल क्यों की गई?

आइए याद करते हैं कि बिंदु उस समय से संबंधित है जब COALESCE को CASE में परिवर्तित किया जाता है। तर्कों में भावों का मूल्यांकन कितनी बार किया जाता है? दो बार!

तो, सबक्वायरी का मूल्यांकन दो बार किया जाता है। यह निष्पादन योजना में डुप्लिकेट नोड्स के साथ दिखाता है।

यह ISNULL की तुलना में COALESCE का उपयोग करके दोहरे तार्किक पठन की भी व्याख्या करता है। यदि आप COALESCE के साथ क्वेरी के निष्पादन योजना XML को देखने की योजना बना रहे हैं, तो यह काफी लंबा है। लेकिन इससे पता चलता है कि सबक्वेरी दो बार निष्पादित की जाएगी।

अब क्या? क्या हम इसे मात दे सकते हैं? बेशक! यदि आपने कभी भी इस तरह की किसी चीज का सामना किया है, जो मुझे लगता है कि दुर्लभ है, तो संभावित समाधान विभाजित करना और जीतना है। या, ISNULL का उपयोग करें यदि यह केवल एक सबक्वेरी है।

सबक्वायरी एक्सप्रेशन का दो बार मूल्यांकन करने से कैसे बचें

सबक्वेरी का दो बार मूल्यांकन करने से बचने का तरीका यहां बताया गया है:

  • एक वैरिएबल घोषित करें और उसे सबक्वेरी का परिणाम असाइन करें।
  • फिर, चर को COALESCE के तर्क के रूप में पास करें।
  • उपश्रेणियों की संख्या के आधार पर समान चरणों को दोहराएं।

जैसा कि मैंने कहा, यह दुर्लभ होना चाहिए, लेकिन अगर ऐसा होता है, तो आप जानते हैं कि अब क्या करना है।

अलगाव के स्तर पर कुछ शब्द

सबक्वेरी का दो बार मूल्यांकन करने से दूसरी समस्या हो सकती है। आपकी क्वेरी के अलगाव स्तर के आधार पर, पहले मूल्यांकन का परिणाम बहु-उपयोगकर्ता परिवेश में दूसरे मूल्यांकन से भिन्न हो सकता है। यह पागलपन है।

स्थिर परिणाम सुनिश्चित करने के लिए, आप स्नैपशॉट अलगाव का उपयोग करने का प्रयास कर सकते हैं। इसके अलावा, आप ISNULL का उपयोग कर सकते हैं। या, जैसा कि ऊपर बताया गया है, यह फूट डालो और जीतो का दृष्टिकोण हो सकता है।

टेकअवे

तो, सार क्या है?

  • हमेशा तार्किक पढ़ने की जांच करें। यह बीते हुए समय से ज्यादा मायने रखता है। बीते हुए समय का सदुपयोग करें और अपने विवेक को छीन लें। आपकी मशीन और उत्पादन सर्वर के हमेशा अलग-अलग परिणाम होंगे। अपने आप को एक विराम दें।
  • हमेशा निष्पादन योजना की जांच करें, ताकि आप जान सकें कि क्या हो रहा है।
  • ध्यान रखें कि जब COALESCE का अनुवाद CASE में किया जाता है, तो भावों का मूल्यांकन दो बार किया जाता है। फिर, एक सबक्वायरी या कुछ इसी तरह की समस्या हो सकती है। COALESCE में उपयोग करने से पहले एक वैरिएबल को सबक्वेरी परिणाम असाइन करना एक समाधान हो सकता है।
  • जो तेज़ है वह तार्किक रीड के परिणामों और निष्पादन योजनाओं पर निर्भर करता है। यह निर्धारित करने के लिए कोई सामान्य नियम नहीं है कि COALESCE या ISNULL तेज़ है या नहीं। अन्यथा, Microsoft इसके बारे में सूचित कर सकता है, जैसा कि उन्होंने HierarchyID और SQL ग्राफ़ में किया था।

आखिरकार, यह वास्तव में निर्भर करता है।

निष्कर्ष

मुझे उम्मीद है कि आपको यह लेख पढ़ने लायक लगा होगा। यहां वे बिंदु हैं जिन पर हमने चर्चा की:

  • COALESCE नल को संभालने का एक तरीका है। कोड में त्रुटियों से बचने के लिए यह एक सुरक्षा जाल है।
  • यह तर्क सूची को स्वीकार करता है और पहला गैर-शून्य मान देता है।
  • क्वेरी प्रोसेसिंग के दौरान यह CASE एक्सप्रेशन में बदल जाता है, लेकिन यह क्वेरी को धीमा नहीं करता है।
  • हालांकि ISNULL में कुछ समानताएं हैं, लेकिन इसमें 7 उल्लेखनीय अंतर हैं।
  • इसका उपयोग WHERE क्लॉज के साथ किया जा सकता है।
  • आखिरकार, यह ISNULL से तेज या धीमा नहीं है।

अगर आपको यह पोस्ट पसंद आती है, तो सोशल मीडिया बटन आपके क्लिक की प्रतीक्षा कर रहे हैं। साझा करना देखभाल कर रहा है।

धन्यवाद।

यह भी पढ़ें

शुरुआती के लिए SQL COALESCE फ़ंक्शन के साथ NULL मानों को प्रभावी ढंग से संभालना

SQL COALESCE फ़ंक्शन का व्यावहारिक उपयोग


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. डेटाबेस संलग्न करते समय प्रवेश निषेध है

  2. SQL सर्वर क्वेरी टाइम आउट कहां क्लॉज पर निर्भर करता है

  3. SQL सर्वर हमेशा उपलब्धता समूह पर:स्थापना और कॉन्फ़िगरेशन। भाग 2

  4. tsql किसी फ़ंक्शन या स्टोर प्रक्रिया से तालिका लौटा रहा है

  5. MS SQL से PostgreSQL में डेटा माइग्रेट करें?