पहचान कॉलम से बेहतर प्रदर्शन करने के लिए Denali अनुक्रम क्यों माना जाता है?


36

उनके उत्तर में, जो बेहतर है: पहचान कॉलम या उत्पन्न अद्वितीय आईडी मान? मर्देनी कहते हैं:

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

मुझे बहुत ज़्यादा यकीन नहीं है। ओरेकल के अनुक्रमों को जानने के बाद , मुझे या तो सम्मिलित करने के लिए एक ट्रिगर बनाना होगा, प्रत्येक प्रविष्टि को एक संग्रहीत कार्यविधि के कॉल में इनकैप्सुलेट करना होगा, या यह प्रार्थना करना होगा कि जब मैं एड-हॉक इंसर्ट करता हूं तो अनुक्रम का ठीक से उपयोग करना नहीं भूलता।

मुझे संदेह है कि दृश्यों के फायदे इतने स्पष्ट हैं।


2
मुझे पता है कि यह आपके सवाल का जवाब नहीं देता है, लेकिन किसी भी प्रदर्शन अंतर से अलग, दृश्यों के अन्य फायदे हैं। उदाहरण के लिए एक अनुक्रम आपको लक्ष्य स्तंभ को अपडेट करने से नहीं रोकता है, जो कि पहचान की बहुत असुविधाजनक सीमा है।
nvogel

जवाबों:


37

मैं यहाँ भी जवाब दूंगा। यह कैसे IDENTITYऔर SEQUENCEकाम के आंतरिक के साथ क्या करना है।

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

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

कैश को बहुत अधिक सेट न करें, क्योंकि इससे उन संख्याओं की संख्या कम हो जाएगी जिनका उपयोग किया जा सकता है: यदि SQL सर्वर क्रैश होना था, तो वर्तमान कैश रेंज में निर्दिष्ट कोई भी मान जो उपयोग नहीं किया गया था, वह खो जाएगा।

पंक्ति प्रविष्टि के लिए, कॉलम के लिए बस एक डिफ़ॉल्ट मान निर्दिष्ट करें, जैसे:

DEFAULT (NEXT VALUE FOR Audit.EventCounter),

21

चूंकि इट्ज़िक बेन गान लेख को 10 के हार्डकॉश कैश आकार में लिखा गया था, IDENTITYऐसा लगता है कि इसे बदल दिया गया है। इस कनेक्ट आइटम पर टिप्पणियों से

पूर्व-आवंटन का आकार स्तंभ के डेटा प्रकार के आकार पर आधारित होता है, जिस पर पहचान गुण परिभाषित होता है। SQL सर्वर पूर्णांक स्तंभ के लिए, सर्वर 1000 मानों की श्रेणी में पहचान आवंटित करता है। बिगिन्ट डेटा के लिए सर्वर 10000 मानों की श्रेणी में पूर्व-आबंटित होता है।

T-SQL क्वैरी पुस्तक निम्न तालिका में शामिल है, लेकिन जोर देती है कि इन मूल्यों को दस्तावेज या अपरिवर्तित होने की गारंटी नहीं कर रहे हैं।

+-----------------+-----------+
|    DataType     | CacheSize |
+-----------------+-----------+
| TinyInt         | 10        |
| SmallInt        | 100       |
| Int             | 1,000     |
| BigInt, Numeric | 10,000    |
+-----------------+-----------+

यहां लेख विभिन्न अनुक्रम कैश आकारों का परीक्षण करता है और बैच आकार सम्मिलित करता है और निम्नलिखित परिणामों के साथ आता है।

यहाँ छवि विवरण दर्ज करें

जो यह दर्शाता है कि बड़े आवेषण के IDENTITYलिए प्रदर्शन करता है SEQUENCE। हालांकि यह कैश आकार 1,000 का परीक्षण नहीं करता है और यह भी कि परिणाम केवल एक परीक्षण है। आवेषण के विभिन्न बैच आकारों के साथ विशेष रूप से कैश आकार 1,000 को देखते हुए मुझे निम्नलिखित परिणाम मिले (प्रत्येक बैच के आकार को 50 बार आज़माते हुए और परिणामों को नीचे के रूप में एकत्रित करना - सभी समय μs में।)

+------------+-----------+-----------+-----------+-----------+-----------+-----------+
|            |             Sequence              |             Identity              |
| Batch Size |    Min    |    Max    |    Avg    |    Min    |    Max    |    Avg    |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+
| 10         | 2,994     | 7,004     | 4,002     | 3,001     | 7,005     | 4,022     |
| 100        | 3,997     | 5,005     | 4,218     | 4,001     | 5,010     | 4,238     |
| 1,000      | 6,001     | 19,013    | 7,221     | 5,982     | 8,006     | 6,709     |
| 10,000     | 26,999    | 33,022    | 28,645    | 24,015    | 34,022    | 26,114    |
| 100,000    | 189,126   | 293,340   | 205,968   | 165,109   | 234,156   | 173,391   |
| 1,000,000  | 2,208,952 | 2,344,689 | 2,269,297 | 2,058,377 | 2,191,465 | 2,098,552 |
+------------+-----------+-----------+-----------+-----------+-----------+-----------+

बड़े बैच आकारों के लिए IDENTITYसंस्करण आम तौर पर तेज लगता है ।

TSQL क्वेरी पुस्तक यह भी बताती है कि IDENTITYअनुक्रम पर प्रदर्शन लाभ क्यों हो सकता है।

IDENTITYतालिका विशिष्ट है और SEQUENCEनहीं है। यदि लॉग बफ़र से पहले मध्य डालने पर आपदा आनी थी, तो पुनर्प्राप्त की गई पहचान से कोई फर्क नहीं पड़ता, यदि पुनर्प्राप्ति प्रक्रिया पहले वाली हो तो भी सम्मिलित हो जाएगी, इसलिए SQL सर्वर हर पहचान पर लॉग बफ़र को फ्लश करने के लिए बाध्य नहीं करता है कैश संबंधित डिस्क लेखन हालांकि अनुक्रम के लिए इसे लागू किया जाता है क्योंकि मूल्य किसी भी उद्देश्य के लिए उपयोग किया जा सकता है - डेटाबेस के बाहर भी। तो ऊपर के उदाहरण में एक लाख आवेषण और 1,000 के कैश आकार के साथ यह एक अतिरिक्त हजार लॉग फ्लश है।

पुन: पेश करने के लिए स्क्रिप्ट

DECLARE @Results TABLE(
  BatchCounter INT,
  NumRows      INT,
  SequenceTime BIGINT,
  IdTime       BIGINT);

DECLARE @NumRows      INT = 10,
        @BatchCounter INT;

WHILE @NumRows <= 1000000
  BEGIN
      SET @BatchCounter = 0;

      WHILE @BatchCounter <= 50
        BEGIN
            --Do inserts using Sequence
            DECLARE @SequenceTimeStart DATETIME2(7) = SYSUTCDATETIME();

            INSERT INTO dbo.t1_Seq1_cache_1000
                        (c1)
            SELECT N
            FROM   [dbo].[TallyTable] (@NumRows)
            OPTION (RECOMPILE);

            DECLARE @SequenceTimeEnd DATETIME2(7) = SYSUTCDATETIME();
            --Do inserts using IDENTITY
            DECLARE @IdTimeStart DATETIME2(7) = SYSUTCDATETIME();

            INSERT INTO dbo.t1_identity
                        (c1)
            SELECT N
            FROM   [dbo].[TallyTable] (@NumRows)
            OPTION (RECOMPILE);

            DECLARE @IdTimeEnd DATETIME2(7) = SYSUTCDATETIME();

            INSERT INTO @Results
            SELECT @BatchCounter,
                   @NumRows,
                   DATEDIFF(MICROSECOND, @SequenceTimeStart, @SequenceTimeEnd) AS SequenceTime,
                   DATEDIFF(MICROSECOND, @IdTimeStart, @IdTimeEnd)             AS IdTime;

            TRUNCATE TABLE dbo.t1_identity;

            TRUNCATE TABLE dbo.t1_Seq1_cache_1000;

            SET @BatchCounter +=1;
        END

      SET @NumRows *= 10;
  END

SELECT NumRows,
       MIN(SequenceTime) AS MinSequenceTime,
       MAX(SequenceTime) AS MaxSequenceTime,
       AVG(SequenceTime) AS AvgSequenceTime,
       MIN(IdTime)       AS MinIdentityTime,
       MAX(IdTime)       AS MaxIdentityTime,
       AVG(IdTime)       AS AvgIdentityTime
FROM   @Results
GROUP  BY NumRows;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.