तार्किक वैश्विक अस्थायी तालिका पर पढ़ता है, लेकिन सत्र-स्तरीय अस्थायी तालिका पर नहीं


11

निम्नलिखित सरल MCVE पर विचार करें:

SET STATISTICS IO, TIME OFF;
USE tempdb;

IF OBJECT_ID(N'tempdb..#t1', N'U') IS NOT NULL DROP TABLE #t1;
CREATE TABLE #t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'tempdb..##t1', N'U') IS NOT NULL DROP TABLE ##t1;
CREATE TABLE ##t1
(
    r int NOT NULL
);

IF OBJECT_ID(N'dbo.s1', N'U') IS NOT NULL DROP TABLE dbo.s1;
CREATE TABLE dbo.s1 
(
    r int NOT NULL
        PRIMARY KEY CLUSTERED
);

INSERT INTO dbo.s1 (r)
SELECT TOP(10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.syscolumns sc1
    CROSS JOIN sys.syscolumns sc2;
GO

जब मैं निम्नलिखित आवेषण चलाता हूं, #t1तो टेम्‍परेचर टेबल के लिए कोई आँकड़े I / O नहीं दिखाता है। हालांकि, में डालने ##t1 करता आंकड़े दिखाएं मैं / अस्थायी तालिका के लिए हे।

SET STATISTICS IO, TIME ON;
GO

INSERT INTO #t1 (r)
SELECT r
FROM dbo.s1;

आँकड़े आउटपुट:

SQL सर्वर पार्स और संकलन समय: 
   सीपीयू समय = 0 एमएस, बीता हुआ समय = 1 एमएस।
टेबल 's1'। स्कैन काउंट 1, लॉजिकल रीड 19, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

 SQL सर्वर निष्पादन समय:
   सीपीयू समय = 16 एमएस, बीता हुआ समय = 9 एमएस।

(10000 पंक्तियाँ प्रभावित)
INSERT INTO ##t1 (r)
SELECT r
FROM dbo.s1;
SQL सर्वर पार्स और संकलन समय: 
   सीपीयू समय = 0 एमएस, बीता हुआ समय = 1 एमएस।
तालिका '## t1'। स्कैन काउंट 0, लॉजिकल रीड्स 10016, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।
टेबल 's1'। स्कैन काउंट 1, लॉजिकल रीड 19, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।

 SQL सर्वर निष्पादन समय:
   सीपीयू समय = 47 एमएस, बीता हुआ समय = 45 एमएस।

(10000 पंक्तियाँ प्रभावित)

जब मैं इसमें केवल सम्मिलित कर रहा हूं तो ## टेम्पर टेबल पर इतने सारे रीड क्यों हैं?

जवाबों:


11

उपयोग INSERT INTOऔर वैश्विक टेम्‍प टेबल का उपयोग करने पर मिनिमल लॉगिंग का उपयोग नहीं किया जा रहा है

का उपयोग करके एक वैश्विक अस्थायी तालिका में एक लाख पंक्तियों को सम्मिलित करना INSERT INTO

INSERT INTO ##t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

SELECT * FROM fn_dblog(NULL, NULL)ऊपर क्वेरी करते समय चलने पर , ~ 1M पंक्तियाँ वापस आ जाती हैं।

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

LOP_INSERT_ROWप्रत्येक पंक्ति + अन्य लॉग डेटा के लिए एक ऑपरेशन।


एक स्थानीय अस्थायी टेबल पर समान डालें

INSERT INTO #t1 (r)
SELECT top(1000000) s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

केवल 700 पंक्तियों तक जा कर लौटा SELECT * FROM fn_dblog(NULL, NULL)

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

न्यूनतम लॉगिंग


का उपयोग करके एक वैश्विक अस्थायी तालिका में एक लाख पंक्तियों को सम्मिलित करना SELECT INTO

SELECT top(1000000) s1.r
INTO ##t2
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

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

SELECT INTO 10k रिकॉर्ड के साथ एक वैश्विक अस्थायी तालिका

SELECT s1.r
INTO ##t2
FROM dbo.s1;

समय और आईओ सांख्यिकी

SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.
Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

 SQL Server Execution Times:
   CPU time = 16 ms,  elapsed time = 10 ms.
SQL Server parse and compile time: 
   CPU time = 0 ms, elapsed time = 0 ms.

इस ब्लॉगपोस्ट के आधार पर हम TABLOCKढेर तालिका पर न्यूनतम लॉगिंग आरंभ करने के लिए जोड़ सकते हैं

INSERT INTO ##t1 WITH(TABLOCK) (r)
SELECT   s1.r
FROM dbo.s1

कम तार्किक पढ़ता है

Table 's1'. Scan count 1, logical reads 19, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(10000 rows affected)

अस्थायी तालिकाओं पर न्यूनतम लॉगिंग प्राप्त करने के तरीके पर @PaulWite द्वारा उत्तर का एक हिस्सा

नहीं। स्थानीय अस्थायी टेबल (# टैम्प) बनाने के सत्र के लिए निजी हैं, इसलिए टेबल लॉक हिंट की आवश्यकता नहीं है। वैश्विक अस्थायी तालिका (## अस्थायी) या अस्थायी तालिका (dbo.temp) के लिए एक टेबल लॉक संकेत की आवश्यकता होगी, क्योंकि इन्हें कई सत्रों से एक्सेस किया जा सकता है।

इसका परीक्षण करने के लिए एक नियमित तालिका बनाना:

CREATE TABLE dbo.bla
(
    r int NOT NULL 
);

इसे 1M रिकॉर्ड के साथ भरना

INSERT INTO bla 
SELECT   top(1000000)s1.r
FROM dbo.s1
CROSS APPLY  dbo.s1 S2;

> 1M तार्किक इस तालिका पर पढ़ता है

Table 's1'. Scan count 17, logical reads 155, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'bla'. Scan count 0, logical reads 1001607, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

पॉल व्हाइट का जवाब वैश्विक अस्थायी तालिका पर बताई गई तार्किक रीड्स की व्याख्या करता है

आम तौर पर, तार्किक रीड लक्ष्य तालिका के लिए रिपोर्ट किए जाते हैं जब सम्मिलित न्यूनतम रूप से लॉग इन नहीं होते हैं।

ये तार्किक रीड नई पंक्तियों को जोड़ने के लिए मौजूदा संरचना में एक जगह खोजने से जुड़े हैं। न्यूनतम रूप से लॉग किए गए आवेषण बल्क-लोडिंग तंत्र का उपयोग करते हैं, जो पूरे नए पृष्ठों / extents को आवंटित करता है (और उसी तरह लक्ष्य संरचना को पढ़ने की आवश्यकता नहीं है)।


निष्कर्ष

निष्कर्ष यह है कि INSERT INTOन्यूनतम लॉगिंग का उपयोग करने में सक्षम नहीं है, जिसके परिणामस्वरूप जब एक वैश्विक अस्थायी तालिका / सामान्य तालिका के साथ संयोजन में उपयोग किया जाता है, तो प्रत्येक सम्मिलित पंक्ति को व्यक्तिगत रूप से tempdb की लॉग फ़ाइल में लॉग किया जाता है। जबकि स्थानीय अस्थायी तालिका / SELECT INTO/ INSERT INTO ... WITH(TABLOCK)न्यूनतम लॉगिंग का उपयोग करने में सक्षम है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.