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

SQL सर्वर एकत्रीकरण के साथ यादृच्छिक (या पहले) मान चुनें

एक है। अनिर्दिष्ट कुल ANY कहा जाता है जो मान्य सिंटैक्स नहीं है, लेकिन आपकी निष्पादन योजनाओं में प्रकट होना संभव है। हालांकि यह कोई प्रदर्शन लाभ प्रदान नहीं करता है।

निम्न तालिका और अनुक्रमणिका संरचना को मानते हुए

CREATE TABLE T
(
id int identity primary key,
[group] char(1) 
)

CREATE NONCLUSTERED INDEX ix ON T([group])

INSERT INTO T
SELECT TOP 1000000 CHAR( 65 + ROW_NUMBER() OVER (ORDER BY @@SPID) % 3)
FROM sys.all_objects o1, sys.all_objects o2, sys.all_objects o3

मैंने नमूना डेटा के साथ भी पॉप्युलेट किया है जैसे कि प्रति समूह कई पंक्तियां हैं।

आपकी मूल क्वेरी

SELECT MAX(id),
       [group]
FROM   T
GROUP  BY [group]  

Table 'T'. Scan count 1, logical reads 1367 और योजना

  |--Stream Aggregate(GROUP BY:([[T].[group]) DEFINE:([Expr1003]=MAX([[T].[id])))
       |--Index Scan(OBJECT:([[T].[ix]), ORDERED FORWARD)

ANY प्राप्त करने के लिए फिर से लिखा गया कुल...

;WITH cte AS
(
SELECT *,
        ROW_NUMBER() OVER (PARTITION BY [group] ORDER BY [group] ) AS RN
FROM T)
SELECT id,
       [group]
FROM    cte     
WHERE RN=1

Table 'T'. Scan count 1, logical reads 1367 और योजना

  |--Stream Aggregate(GROUP BY:([[T].[group]) DEFINE:([[T].[id]=ANY([[T].[id])))
       |--Index Scan(OBJECT:([[T].[ix]), ORDERED FORWARD)

भले ही संभावित रूप से SQL सर्वर पहला मान मिलते ही समूह को संसाधित करना बंद कर सकता है और अगले पर छोड़ देता है जो ऐसा नहीं करता है। यह अभी भी सभी पंक्तियों को संसाधित करता है और तार्किक पठन समान हैं।

इस विशेष उदाहरण के लिए समूह में कई पंक्तियों के साथ एक अधिक कुशल संस्करण एक पुनरावर्ती CTE होगा।

WITH    RecursiveCTE
AS      (
        SELECT TOP 1 id, [group]
        FROM T
        ORDER BY [group]
        UNION   ALL
        SELECT  R.id, R.[group]
        FROM    (
                SELECT  T.*,
                        rn = ROW_NUMBER() OVER (ORDER BY (SELECT 0))
                FROM    T
                JOIN    RecursiveCTE R
                        ON  R.[group] < T.[group]
                ) R
        WHERE   R.rn = 1
        )
SELECT  *
FROM    RecursiveCTE
OPTION  (MAXRECURSION 0);

जो देता है

Table 'Worktable'. Scan count 2, logical reads 19
Table 'T'. Scan count 4, logical reads 12

तार्किक पठन बहुत कम है क्योंकि यह प्रति समूह पहली पंक्ति को पुनः प्राप्त करता है और फिर रिकॉर्ड के भार को पढ़ने के बजाय अगले समूह में खोजता है जो अंतिम परिणाम में योगदान नहीं करते हैं।




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

  2. सी # से डेटाबेस को कैसे पुनर्स्थापित करें

  3. SQL सर्वर की दिनांक, समय और डेटाटाइमऑफ़सेट के लिए समतुल्य C# डेटा प्रकार क्या हैं?

  4. ग्रुप बाय क्वेरी में लापता महीने शामिल करें

  5. मैं एक अद्वितीय बाधा कैसे बना सकता हूं जो नल को भी अनुमति देता है?