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

लूप के बिना एक सेट या अनुक्रम उत्पन्न करें - भाग 2

अपनी पिछली पोस्ट में, मैंने 1 से 1,000 तक सन्निहित संख्याओं के अनुक्रम को उत्पन्न करने के तरीकों के बारे में बात की थी। अब मैं पैमाने के अगले स्तरों के बारे में बात करना चाहता हूं:50,000 और 1,00,000 संख्याओं के सेट बनाना।

50,000 संख्याओं का एक सेट बनाना

इस श्रृंखला को शुरू करते समय, मैं वास्तव में उत्सुक था कि विभिन्न दृष्टिकोण संख्याओं के बड़े सेट तक कैसे पहुंचेंगे। कम अंत में मैं यह जानकर थोड़ा निराश हुआ कि मेरा पसंदीदा तरीका - sys.all_objects का उपयोग कर रहा है - सबसे कारगर तरीका नहीं था। लेकिन इन विभिन्न तकनीकों का पैमाना 50,000 पंक्तियों तक कैसे होगा?

    नंबर तालिका

    चूंकि हमने पहले ही 1,000,000 पंक्तियों के साथ एक नंबर तालिका बना ली है, यह क्वेरी लगभग समान रहती है:

    SELECT TOP (50000) n FROM dbo.Numbers ORDER BY n;

    योजना:

    spt_values

    चूँकि spt_values . में केवल ~2,500 पंक्तियाँ हैं , यदि हम इसे अपने सेट जनरेटर के स्रोत के रूप में उपयोग करना चाहते हैं तो हमें थोड़ा और रचनात्मक होने की आवश्यकता है। एक बड़ी तालिका का अनुकरण करने का एक तरीका है CROSS JOIN यह खुद के खिलाफ। अगर हमने वह कच्चा किया तो हम ~ 2,500 पंक्तियों के साथ समाप्त हो जाएंगे (6 मिलियन से अधिक)। केवल 50,000 पंक्तियों की आवश्यकता है, हमें लगभग 224 पंक्तियों का वर्ग चाहिए। तो हम यह कर सकते हैं:

    ;WITH x AS 
    (
      SELECT TOP (224) number FROM [master]..spt_values
    )
    SELECT TOP (50000) n = ROW_NUMBER() OVER (ORDER BY x.number) 
    FROM x CROSS JOIN x AS y
    ORDER BY n;

    ध्यान दें कि यह इस भिन्नता के समतुल्य है, लेकिन उससे अधिक संक्षिप्त है:

    SELECT TOP (50000) n = ROW_NUMBER() OVER (ORDER BY x.number) 
    FROM 
    (SELECT TOP (224) number FROM [master]..spt_values) AS x
    CROSS JOIN
    (SELECT TOP (224) number FROM [master]..spt_values) AS y
    ORDER BY n;

    दोनों ही मामलों में, योजना इस तरह दिखती है:

    sys.all_objects

    जैसे spt_values , sys.all_objects हमारी 50,000 पंक्ति की आवश्यकता को अपने आप पूरी तरह से संतुष्ट नहीं करता है, इसलिए हमें एक समान CROSS JOIN करने की आवश्यकता होगी ।

    ;;WITH x AS 
    (
      SELECT TOP (224) [object_id] FROM sys.all_objects
    )
    SELECT TOP (50000) n = ROW_NUMBER() OVER (ORDER BY x.[object_id]) 
    FROM x CROSS JOIN x AS y 
    ORDER BY n;

    योजना:

    स्टैक्ड सीटीई

    ठीक 50,000 पंक्तियाँ प्राप्त करने के लिए हमें अपने स्टैक्ड सीटीई में केवल एक मामूली समायोजन करने की आवश्यकता है:

    ;WITH e1(n) AS
    (
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
    ), -- 10
    e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
    e3(n) AS (SELECT 1 FROM e2 CROSS JOIN e2 AS b), -- 100*100
    e4(n) AS (SELECT 1 FROM e3 CROSS JOIN (SELECT TOP 5 n FROM e1) AS b)  -- 5*10000
      SELECT n = ROW_NUMBER() OVER (ORDER BY n) FROM e4 ORDER BY n;

    योजना:

    पुनरावर्ती सीटीई

    हमारे पुनरावर्ती CTE से 50,000 पंक्तियों को प्राप्त करने के लिए और भी कम महत्वपूर्ण परिवर्तन की आवश्यकता है:WHERE बदलें खंड को 50,000 में बदलें और MAXRECURSION बदलें शून्य का विकल्प।

    ;WITH n(n) AS
    (
        SELECT 1
        UNION ALL
        SELECT n+1 FROM n WHERE n < 50000
    )
    SELECT n FROM n ORDER BY n
    OPTION (MAXRECURSION 0);

    योजना:

    इस मामले में सॉर्ट पर एक चेतावनी आइकन है - जैसा कि यह पता चला है, मेरे सिस्टम पर, टेम्पर्ड को फैलाने के लिए आवश्यक सॉर्ट। हो सकता है कि आप अपने सिस्टम पर कोई रिसाव न देखें, लेकिन यह इस तकनीक के लिए आवश्यक संसाधनों के बारे में एक चेतावनी होनी चाहिए।

    प्रदर्शन

    परीक्षणों के अंतिम सेट की तरह, हम प्रत्येक तकनीक की तुलना करेंगे, जिसमें ठंडे और गर्म कैश, और संपीड़ित और असम्पीडित दोनों के साथ Numbers तालिका शामिल है:


    रनटाइम, मिलीसेकंड में, 50,000 सन्निहित संख्याएं जेनरेट करने के लिए

    बेहतर दृश्य प्राप्त करने के लिए, आइए पुनरावर्ती CTE को हटा दें, जो इस परीक्षण में कुल कुत्ता था और जो परिणामों को खराब करता है:


    रनटाइम, मिलीसेकंड में, 50,000 सन्निहित संख्याएं उत्पन्न करने के लिए (पुनरावर्ती को छोड़कर) सीटीई)

    1,000 पंक्तियों में, संपीड़ित और असम्पीडित के बीच का अंतर मामूली था, क्योंकि क्वेरी को केवल क्रमशः 8 और 9 पृष्ठों को पढ़ने की आवश्यकता थी। 50,000 पंक्तियों में, अंतर थोड़ा चौड़ा हो जाता है:74 पृष्ठ बनाम 113। हालांकि, डेटा को डीकंप्रेस करने की कुल लागत I/O में बचत से अधिक लगती है। तो, 50,000 पंक्तियों में, एक असम्पीडित संख्या तालिका एक सन्निहित सेट प्राप्त करने का सबसे कुशल तरीका प्रतीत होता है - हालांकि, माना जाता है कि लाभ मामूली है।

1,000,000 संख्याओं का समूह बनाना

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

    नंबर तालिका

    यहाँ कोई आश्चर्य की बात नहीं है, अब हमारी क्वेरी है:

    SELECT TOP 1000000 n FROM dbo.Numbers ORDER BY n;

    TOP कड़ाई से आवश्यक नहीं है, लेकिन ऐसा केवल इसलिए है क्योंकि हम जानते हैं कि हमारी संख्या तालिका और हमारे वांछित आउटपुट में पंक्तियों की संख्या समान है। योजना अभी भी पिछले परीक्षणों के समान ही है:

    spt_values

    CROSS JOIN प्राप्त करने के लिए जो 1,000,000 पंक्तियाँ उत्पन्न करता है, हमें 1,000 पंक्तियों को चुकता करने की आवश्यकता है:

    ;WITH x AS 
    (
      SELECT TOP (1000) number FROM [master]..spt_values
    )
    SELECT n = ROW_NUMBER() OVER (ORDER BY x.number) 
    FROM x CROSS JOIN x AS y ORDER BY n;

    योजना:

    sys.all_objects

    फिर से, हमें 1,000 पंक्तियों के क्रॉस उत्पाद की आवश्यकता है:

    ;WITH x AS 
    (
      SELECT TOP (1000) [object_id] FROM sys.all_objects
    )
    SELECT n = ROW_NUMBER() OVER (ORDER BY x.[object_id]) 
    FROM x CROSS JOIN x AS y ORDER BY n;

    योजना:

    स्टैक्ड सीटीई

    स्टैक्ड CTE के लिए, हमें बस CROSS JOIN . के थोड़े अलग संयोजन की आवश्यकता है s 1,00,000 पंक्तियाँ प्राप्त करने के लिए:

    ;WITH e1(n) AS
    (
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL 
        SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
    ), -- 10
    e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
    e3(n) AS (SELECT 1 FROM e1 CROSS JOIN e2 AS b), -- 10*100
    e4(n) AS (SELECT 1 FROM e3 CROSS JOIN e3 AS b)  -- 1000*1000
      SELECT n = ROW_NUMBER() OVER (ORDER BY n) FROM e4 ORDER BY n;

    योजना:

    इस पंक्ति आकार में, आप देख सकते हैं कि स्टैक्ड CTE समाधान समानांतर हो जाता है। इसलिए मैंने MAXDOP 1 . के साथ एक संस्करण भी चलाया पहले की तरह एक समान योजना आकार प्राप्त करने के लिए, और यह देखने के लिए कि क्या समानता वास्तव में मदद करती है:

    पुनरावर्ती CTE

    पुनरावर्ती सीटीई में फिर से बस एक मामूली बदलाव है; केवल WHERE क्लॉज को बदलने की जरूरत है:

    ;WITH n(n) AS
    (
        SELECT 1
        UNION ALL
        SELECT n+1 FROM n WHERE n < 1000000
    )
    SELECT n FROM n ORDER BY n
    OPTION (MAXRECURSION 0);

    योजना:

    प्रदर्शन

    एक बार फिर हम देखते हैं कि रिकर्सिव सीटीई का प्रदर्शन बेहद खराब है:


    रनटाइम, मिलीसेकंड में, 1,000,000 सन्निहित संख्याएं उत्पन्न करने के लिए

    ग्राफ़ से उस बाहरी को हटाकर, हमें प्रदर्शन के बारे में एक बेहतर तस्वीर मिलती है:


    रनटाइम, मिलीसेकंड में, 1,000,000 सन्निहित संख्याएं उत्पन्न करने के लिए (पुनरावर्ती को छोड़कर) सीटीई)

    जबकि फिर से हम असम्पीडित संख्या तालिका (कम से कम एक गर्म कैश के साथ) को विजेता के रूप में देखते हैं, इस पैमाने पर भी अंतर इतना उल्लेखनीय नहीं है।

जारी रखने के लिए...

अब जबकि हमने संख्याओं का एक क्रम उत्पन्न करने के लिए मुट्ठी भर दृष्टिकोणों का अच्छी तरह से पता लगा लिया है, हम तारीखों पर आगे बढ़ेंगे। इस श्रृंखला की अंतिम पोस्ट में, हम एक सेट के रूप में एक तिथि सीमा के निर्माण के माध्यम से चलेंगे, जिसमें एक कैलेंडर तालिका का उपयोग और कुछ उपयोग के मामले शामिल हैं जहां यह आसान हो सकता है।

[ भाग 1 | भाग 2 | भाग 3 ]

परिशिष्ट :पंक्तियों की संख्या

हो सकता है कि आप पंक्तियों की सटीक संख्या उत्पन्न करने का प्रयास नहीं कर रहे हों; इसके बजाय आप बहुत सी पंक्तियों को उत्पन्न करने का एक सीधा तरीका चाहते हैं। निम्नलिखित कैटलॉग दृश्यों के संयोजनों की एक सूची है जो आपको विभिन्न पंक्ति गणनाएं प्रदान करेगा यदि आप केवल SELECT करते हैं बिना WHERE खंड। ध्यान दें कि ये नंबर इस बात पर निर्भर करेंगे कि आप आरटीएम में हैं या सर्विस पैक पर (चूंकि कुछ सिस्टम ऑब्जेक्ट जुड़ते या संशोधित होते हैं), और यह भी कि आपके पास एक खाली डेटाबेस है या नहीं।

<वें colspan=3>पंक्ति गणना
स्रोत
SQL Server 2008 R2 एसक्यूएल सर्वर 2012 एसक्यूएल सर्वर 2014
मास्टर..spt_values

2,508

2,515 2,519
मास्टर..spt_values ​​क्रॉस जॉइन मास्टर..spt_values

6,290,064

6,325,225 6,345,361
sys.all_objects

1,990

2,089 2,165
sys.all_columns

5,157

7,276 8,560
sys.all_objects क्रॉस जॉइन sys.all_objects

3,960,100

4,363,921 4,687,225
sys.all_objects क्रॉस जॉइन sys.all_columns

10,262,430

15,199,564 18,532,400
sys.all_columns क्रॉस जॉइन sys.all_columns

26,594,649

52,940,176 73,273,600

तालिका 1:विभिन्न कैटलॉग दृश्य प्रश्नों के लिए पंक्ति गणना


  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. फ्लैश कैश में टेबल पिन करना

  3. क्या स्ट्रिंग ऑपरेटर "+" इतना आसान है?

  4. एसक्यूएल जहां स्टेटमेंट

  5. जावा में फोर्क/जॉइन फ्रेमवर्क के साथ समानांतर प्रोग्रामिंग मूल बातें