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

सात SQL सर्वर प्रकार के आंतरिक भाग - भाग 2

सात SQL सर्वर सॉर्ट कार्यान्वयन वर्ग हैं:

  1. CQScanSortNew
  2. CQScanTopSortNew
  3. CQScanIndexSortNew
  4. CQScanPartitionSortNew (केवल SQL सर्वर 2014)
  5. CQScanInMemSortNew
  6. इन-मेमोरी OLTP (हेकाटन) मूल रूप से संकलित प्रक्रिया टॉप एन सॉर्ट (केवल SQL सर्वर 2014)
  7. इन-मेमोरी OLTP (हेकाटन) मूल रूप से संकलित प्रक्रिया सामान्य सॉर्ट (केवल SQL सर्वर 2014)

पहले चार प्रकारों को इस लेख के भाग एक में शामिल किया गया था।

5. CQScanInMemSortNew

इस प्रकार के वर्ग में कई दिलचस्प विशेषताएं हैं, उनमें से कुछ अद्वितीय हैं:

  • जैसा कि नाम से पता चलता है, यह हमेशा पूरी तरह से मेमोरी में छा जाता है; यह कभी भी tempdb तक नहीं फैलेगा
  • सॉर्टिंग हमेशा मानक C रन-टाइम लाइब्रेरी MSVCR100 में Quicksort qsort_s का उपयोग करके की जाती है
  • यह तीनों प्रकार के तार्किक प्रकार का प्रदर्शन कर सकता है:सामान्य, शीर्ष N, और विशिष्ट प्रकार
  • इसका उपयोग क्लस्टर्ड कॉलमस्टोर प्रति-विभाजन सॉफ्ट प्रकार के लिए किया जा सकता है (भाग 1 में अनुभाग 4 देखें)
  • कार्यान्वयन से ठीक पहले आरक्षित होने के बजाय इसके द्वारा उपयोग की जाने वाली मेमोरी को योजना के साथ कैश किया जा सकता है
  • इसे निष्पादन योजनाओं में इन-मेमोरी सॉर्ट के रूप में पहचाना जा सकता है
  • अधिकतम 500 मानों को क्रमबद्ध किया जा सकता है
  • इसका उपयोग इंडेक्स-बिल्डिंग प्रकार के लिए कभी नहीं किया जाता है (भाग 1 में खंड 3 देखें)

CQScanInMemSortNew एक प्रकार का वर्ग है जिसका आप अक्सर सामना नहीं करेंगे। चूंकि यह हमेशा एक मानक पुस्तकालय क्विकॉर्ट एल्गोरिथ्म का उपयोग करके मेमोरी में सॉर्ट करता है, यह सामान्य डेटाबेस सॉर्टिंग कार्यों के लिए एक अच्छा विकल्प नहीं होगा। वास्तव में, इस प्रकार के वर्ग का उपयोग केवल तभी किया जाता है जब इसके सभी इनपुट रनटाइम स्थिरांक होते हैं (@variable संदर्भों सहित)। एक निष्पादन योजना के नजरिए से, इसका मतलब है कि सॉर्ट ऑपरेटर को इनपुट एक लगातार स्कैन होना चाहिए ऑपरेटर, जैसा कि नीचे दिए गए उदाहरण प्रदर्शित करते हैं:

-- Regular Sort on system scalar functions
SELECT X.i 
FROM 
(
    SELECT @@TIMETICKS UNION ALL
    SELECT @@TOTAL_ERRORS UNION ALL
    SELECT @@TOTAL_READ UNION ALL
    SELECT @@TOTAL_WRITE
) AS X (i)
ORDER BY X.i;
 
-- Distinct Sort on constant literals
WITH X (i) AS
(
    SELECT 3 UNION ALL
    SELECT 1 UNION ALL
    SELECT 1 UNION ALL
    SELECT 2
)
SELECT DISTINCT X.i
FROM X
ORDER BY X.i;
 
-- Top N Sort on variables, constants, and functions
DECLARE
    @x integer = 1,
    @y integer = 2;
 
SELECT TOP (1) 
    X.i
FROM 
(
    VALUES
        (@x), (@y), (123), 
        (@@CONNECTIONS)
) AS X (i)
ORDER BY X.i;

निष्पादन योजनाएं हैं:

छँटाई के दौरान एक विशिष्ट कॉल स्टैक नीचे दिखाया गया है। MSVCR100 लाइब्रेरी में qsort_s को कॉल पर ध्यान दें:

ऊपर दिखाए गए सभी तीन निष्पादन योजनाएं CQScanInMemSortNew का उपयोग करके इन-मेमोरी प्रकार हैं सॉर्ट मेमोरी को कैश करने के लिए पर्याप्त इनपुट के साथ। यह जानकारी निष्पादन योजनाओं में डिफ़ॉल्ट रूप से प्रकट नहीं होती है, लेकिन इसे अनिर्दिष्ट ट्रेस ध्वज 8666 का उपयोग करके प्रकट किया जा सकता है। जब वह ध्वज सक्रिय होता है, तो सॉर्ट ऑपरेटर के लिए अतिरिक्त गुण दिखाई देते हैं:

कैशे बफर इस उदाहरण में 62 पंक्तियों तक सीमित है जैसा कि नीचे दिखाया गया है:

-- Cache buffer limited to 62 rows
SELECT X.i
FROM
(
    VALUES 
    (001),(002),(003),(004),(005),(006),(007),(008),(009),(010),
    (011),(012),(013),(014),(015),(016),(017),(018),(019),(020),
    (021),(022),(023),(024),(025),(026),(027),(028),(029),(030),
    (031),(032),(033),(034),(035),(036),(037),(038),(039),(040),
    (041),(042),(043),(044),(045),(046),(047),(048),(049),(050),
    (051),(052),(053),(054),(055),(056),(057),(058),(059),(060),
    (061),(062)--, (063)
) AS X (i)
ORDER BY X.i;

1 से 0 में सॉर्ट कैश बफ़र गुण परिवर्तन देखने के लिए उस स्क्रिप्ट में अंतिम आइटम को अनकम्मेंट करें:

जब बफर को कैश नहीं किया जाता है, तो इन-मेमोरी सॉर्ट को मेमोरी आवंटित करनी चाहिए क्योंकि यह इनिशियलाइज़ होता है और आवश्यकतानुसार यह इसके इनपुट से पंक्तियों को पढ़ता है। जब एक कैश्ड बफ़र का उपयोग किया जा सकता है, तो इस स्मृति आवंटन कार्य से बचा जाता है।

निम्न स्क्रिप्ट का उपयोग यह प्रदर्शित करने के लिए किया जा सकता है कि CQScanInMemSortNew के लिए आइटम की अधिकतम संख्या इन-मेमोरी क्विकॉर्ट 500 है:

SELECT X.i
FROM
(
    VALUES 
    (001),(002),(003),(004),(005),(006),(007),(008),(009),(010),
    (011),(012),(013),(014),(015),(016),(017),(018),(019),(020),
    (021),(022),(023),(024),(025),(026),(027),(028),(029),(030),
    (031),(032),(033),(034),(035),(036),(037),(038),(039),(040),
    (041),(042),(043),(044),(045),(046),(047),(048),(049),(050),
    (051),(052),(053),(054),(055),(056),(057),(058),(059),(060),
    (061),(062),(063),(064),(065),(066),(067),(068),(069),(070),
    (071),(072),(073),(074),(075),(076),(077),(078),(079),(080),
    (081),(082),(083),(084),(085),(086),(087),(088),(089),(090),
    (091),(092),(093),(094),(095),(096),(097),(098),(099),(100),
    (101),(102),(103),(104),(105),(106),(107),(108),(109),(110),
    (111),(112),(113),(114),(115),(116),(117),(118),(119),(120),
    (121),(122),(123),(124),(125),(126),(127),(128),(129),(130),
    (131),(132),(133),(134),(135),(136),(137),(138),(139),(140),
    (141),(142),(143),(144),(145),(146),(147),(148),(149),(150),
    (151),(152),(153),(154),(155),(156),(157),(158),(159),(160),
    (161),(162),(163),(164),(165),(166),(167),(168),(169),(170),
    (171),(172),(173),(174),(175),(176),(177),(178),(179),(180),
    (181),(182),(183),(184),(185),(186),(187),(188),(189),(190),
    (191),(192),(193),(194),(195),(196),(197),(198),(199),(200),
    (201),(202),(203),(204),(205),(206),(207),(208),(209),(210),
    (211),(212),(213),(214),(215),(216),(217),(218),(219),(220),
    (221),(222),(223),(224),(225),(226),(227),(228),(229),(230),
    (231),(232),(233),(234),(235),(236),(237),(238),(239),(240),
    (241),(242),(243),(244),(245),(246),(247),(248),(249),(250),
    (251),(252),(253),(254),(255),(256),(257),(258),(259),(260),
    (261),(262),(263),(264),(265),(266),(267),(268),(269),(270),
    (271),(272),(273),(274),(275),(276),(277),(278),(279),(280),
    (281),(282),(283),(284),(285),(286),(287),(288),(289),(290),
    (291),(292),(293),(294),(295),(296),(297),(298),(299),(300),
    (301),(302),(303),(304),(305),(306),(307),(308),(309),(310),
    (311),(312),(313),(314),(315),(316),(317),(318),(319),(320),
    (321),(322),(323),(324),(325),(326),(327),(328),(329),(330),
    (331),(332),(333),(334),(335),(336),(337),(338),(339),(340),
    (341),(342),(343),(344),(345),(346),(347),(348),(349),(350),
    (351),(352),(353),(354),(355),(356),(357),(358),(359),(360),
    (361),(362),(363),(364),(365),(366),(367),(368),(369),(370),
    (371),(372),(373),(374),(375),(376),(377),(378),(379),(380),
    (381),(382),(383),(384),(385),(386),(387),(388),(389),(390),
    (391),(392),(393),(394),(395),(396),(397),(398),(399),(400),
    (401),(402),(403),(404),(405),(406),(407),(408),(409),(410),
    (411),(412),(413),(414),(415),(416),(417),(418),(419),(420),
    (421),(422),(423),(424),(425),(426),(427),(428),(429),(430),
    (431),(432),(433),(434),(435),(436),(437),(438),(439),(440),
    (441),(442),(443),(444),(445),(446),(447),(448),(449),(450),
    (451),(452),(453),(454),(455),(456),(457),(458),(459),(460),
    (461),(462),(463),(464),(465),(466),(467),(468),(469),(470),
    (471),(472),(473),(474),(475),(476),(477),(478),(479),(480),
    (481),(482),(483),(484),(485),(486),(487),(488),(489),(490),
    (491),(492),(493),(494),(495),(496),(497),(498),(499),(500)
--,    (501)
) AS X (i)
ORDER BY X.i;

फिर से, इनमेमरी . देखने के लिए अंतिम आइटम को अनकम्मेंट करें संपत्ति परिवर्तन को 1 से 0 में क्रमित करें। ऐसा होने पर, CQScanInMemSortNew या तो CQScanSortNew . द्वारा प्रतिस्थापित किया जाता है (अनुभाग 1 देखें) या CQScanTopSortNew (धारा 2)। एक गैर-CQScanInMemSortNew सॉर्ट अभी भी स्मृति में किया जा सकता है, निश्चित रूप से, यह सिर्फ एक अलग एल्गोरिदम का उपयोग करता है, और इसे tempdb तक फैलाने की अनुमति है यदि आवश्यक हो।

6. इन-मेमोरी OLTP मूल रूप से संकलित संग्रहीत कार्यविधि टॉप एन सॉर्ट

इन-मेमोरी ओएलटीपी (पहले कोड-नाम हेकाटन) का वर्तमान कार्यान्वयन मूल रूप से संकलित संग्रहीत कार्यविधियों में एक प्राथमिकता कतार का उपयोग करता है, जिसके बाद शीर्ष एन सॉर्ट के लिए qsort_s होता है, जब निम्नलिखित शर्तें पूरी होती हैं:

  • क्वेरी में ORDER BY क्लॉज के साथ TOP (N) शामिल है
  • N का मान एक स्थिर अक्षर है (चर नहीं)
  • N का अधिकतम मान 8192 है; यद्यपि
  • जुड़ने या एकत्रीकरण की उपस्थिति यहां दस्तावेज के अनुसार 8192 मान को कम कर सकती है

निम्नलिखित कोड 4000 पंक्तियों वाली एक हेकाटन तालिका बनाता है:

CREATE DATABASE InMemoryOLTP;
GO
-- Add memory optimized filegroup
ALTER DATABASE InMemoryOLTP
ADD FILEGROUP InMemoryOLTPFileGroup 
CONTAINS MEMORY_OPTIMIZED_DATA;
GO
-- Add file (adjust path if necessary)
ALTER DATABASE InMemoryOLTP
ADD FILE
(
	NAME = N'IMOLTP', 
	FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL12.SQL2014\MSSQL\DATA\IMOLTP.hkf'
)
TO FILEGROUP InMemoryOLTPFileGroup;
GO
USE InMemoryOLTP;
GO
CREATE TABLE dbo.Test
(
    col1 integer NOT NULL,
    col2 integer NOT NULL,
    col3 integer NOT NULL,
 
    CONSTRAINT PK_dbo_Test
    PRIMARY KEY NONCLUSTERED HASH (col1)
    WITH (BUCKET_COUNT = 8192)
)
WITH
(
    MEMORY_OPTIMIZED = ON,
    DURABILITY = SCHEMA_ONLY
);
GO
-- Add numbers from 1-4000 using
-- Itzik Ben-Gan's number generator
WITH
  L0   AS (SELECT 1 AS c UNION ALL SELECT 1),
  L1   AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
  L2   AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
  L3   AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
  L4   AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
  L5   AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
  Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5)
INSERT dbo.Test
    (col1, col2, col3)
SELECT 
    N.n,
    ABS(CHECKSUM(NEWID())),
    ABS(CHECKSUM(NEWID()))
FROM Nums AS N
WHERE N.n BETWEEN 1 AND 4000;

अगली स्क्रिप्ट मूल रूप से संकलित संग्रहीत कार्यविधि में एक उपयुक्त टॉप एन सॉर्ट बनाती है:

-- Natively-compiled Top N Sort stored procedure
CREATE PROCEDURE dbo.TestP
WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION
AS
BEGIN ATOMIC 
WITH 
(
    TRANSACTION ISOLATION LEVEL = SNAPSHOT, 
    LANGUAGE = N'us_english'
)
    SELECT TOP (2) T.col2 
    FROM dbo.Test AS T
    ORDER BY T.col2
END;
GO
EXECUTE dbo.TestP;

अनुमानित निष्पादन योजना है:

निष्पादन के दौरान कैप्चर किया गया कॉल स्टैक, प्रगति में प्राथमिकता कतार में सम्मिलित करना दिखाता है:

प्राथमिकता कतार का निर्माण पूरा होने के बाद, अगला कॉल स्टैक मानक पुस्तकालय क्विकॉर्ट के माध्यम से एक अंतिम पास दिखाता है:

xtp_p_* उन कॉल स्टैक में दिखाया गया पुस्तकालय स्थानीय SQL सर्वर इंस्टेंस पर सहेजे गए स्रोत कोड के साथ संग्रहीत प्रक्रिया के लिए मूल रूप से संकलित डीएल है। स्रोत कोड स्वचालित रूप से संग्रहीत कार्यविधि परिभाषा से उत्पन्न होता है। उदाहरण के लिए, इस मूल संग्रहीत कार्यविधि के लिए C फ़ाइल में निम्नलिखित अंश हैं:

यह उतना ही करीब है जितना हम SQL सर्वर स्रोत कोड तक पहुंच प्राप्त कर सकते हैं।

7. इन-मेमोरी OLTP मूल रूप से संकलित संग्रहीत कार्यविधि सॉर्ट करें

मूल रूप से संकलित प्रक्रियाएं वर्तमान में विशिष्ट सॉर्ट का समर्थन नहीं करती हैं, लेकिन सेट के आकार पर किसी भी प्रतिबंध के बिना गैर-विशिष्ट सामान्य सॉर्टिंग समर्थित है। प्रदर्शित करने के लिए, हम पहले परीक्षण तालिका में 6,000 पंक्तियाँ जोड़ेंगे, कुल 10,000 पंक्तियाँ देंगे:

WITH
  L0   AS (SELECT 1 AS c UNION ALL SELECT 1),
  L1   AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B),
  L2   AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B),
  L3   AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B),
  L4   AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B),
  L5   AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B),
  Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS n FROM L5)
INSERT dbo.Test
    (col1, col2, col3)
SELECT 
    N.n,
    ABS(CHECKSUM(NEWID())),
    ABS(CHECKSUM(NEWID()))
FROM Nums AS N
WHERE N.n BETWEEN 4001 AND 10000;

अब हम पिछली परीक्षण प्रक्रिया को छोड़ सकते हैं (मूल रूप से संकलित प्रक्रियाओं को वर्तमान में बदला नहीं जा सकता है) और एक नया बना सकते हैं जो 10,000 पंक्तियों का एक सामान्य (शीर्ष-एन नहीं) प्रकार का प्रदर्शन करता है:

DROP PROCEDURE dbo.TestP;
GO
CREATE PROCEDURE dbo.TestP
WITH EXECUTE AS OWNER, SCHEMABINDING, NATIVE_COMPILATION
AS
BEGIN ATOMIC 
WITH 
(
    TRANSACTION ISOLATION LEVEL = SNAPSHOT, 
    LANGUAGE = N'us_english'
)
    SELECT T.col2 
    FROM dbo.Test AS T
    ORDER BY T.col2
END;
GO
EXECUTE dbo.TestP;

अनुमानित निष्पादन योजना है:

इस प्रकार के निष्पादन का पता लगाने से पता चलता है कि यह मानक पुस्तकालय क्विकसॉर्ट का उपयोग करके फिर से कई छोटे सॉर्ट किए गए रन उत्पन्न करके शुरू होता है:

एक बार यह प्रक्रिया पूरी हो जाने के बाद, सॉर्ट किए गए रन को प्राथमिकता कतार योजना का उपयोग करके मर्ज कर दिया जाता है:

फिर से, प्रक्रिया के लिए सी स्रोत कोड कुछ विवरण दिखाता है:

भाग 2 का सारांश

  • CQScanInMemSortNew हमेशा एक इन-मेमोरी क्विकॉर्ट है। यह लगातार स्कैन से 500 पंक्तियों तक सीमित है, और छोटे इनपुट के लिए इसकी सॉर्ट मेमोरी को कैश कर सकता है। एक प्रकार की पहचान CQScanInMemSortNew . के रूप में की जा सकती है ट्रेस फ़्लैग 8666 द्वारा उजागर निष्पादन योजना गुणों का उपयोग करके सॉर्ट करें।
  • हेकाटन नेटिव संकलित टॉप एन सॉर्ट को एन <=8192 के लिए एक निरंतर शाब्दिक मान की आवश्यकता होती है और एक प्राथमिकता कतार का उपयोग करके एक मानक क्विकॉर्ट के बाद सॉर्ट करता है
  • हेकाटन देशी संकलित सामान्य सॉर्ट किसी भी संख्या में पंक्तियों को सॉर्ट कर सकता है, सॉर्ट रन उत्पन्न करने के लिए मानक लाइब्रेरी क्विकसॉर्ट का उपयोग कर सकता है, और रन को संयोजित करने के लिए प्राथमिकता कतार मर्ज सॉर्ट कर सकता है। यह डिस्टिंक्ट सॉर्ट का समर्थन नहीं करता है।

  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. कर्सर का उपयोग किए बिना प्रत्येक पंक्ति के लिए SQL कॉल संग्रहीत प्रक्रिया

  4. SQL सर्वर में प्राथमिक कुंजी

  5. SQL सर्वर चलाने वाले दो डॉकटर कंटेनरों के बीच एक लिंक्ड सर्वर बनाएँ (T-SQL उदाहरण)