नॉन-पर्सेंटेड कंप्यूटेड कॉलम SQL सर्वर पर नॉन-क्लस्टर्ड इंडेक्स बनाना


10

मैं किसी भी दस्तावेज को खोजने के लिए संघर्ष कर रहा हूं कि कैसे SQL सर्वर वास्तव में एक गैर-निरंतर कम्प्यूटेड कॉलम संग्रहीत करता है।

निम्नलिखित उदाहरण लें:

--SCHEMA
CREATE TABLE dbo.Invoice
(
    InvoiceID INT IDENTITY(1, 1) PRIMARY KEY,
    CustomerID INT FOREIGN KEY REFERENCES dbo.Customer(CustomerID),
    InvoiceStatus NVARCHAR(50) NOT NULL,
    InvoiceStatusID AS CASE InvoiceStatus 
                         WHEN 'Sent' THEN 1 
                         WHEN 'Complete' THEN 2
                         WHEN 'Received' THEN 3
                       END
)
GO

--INDEX
CREATE NONCLUSTERED INDEX IX_Invoice ON Invoice
(
    CustomerID ASC
)
INCLUDE
(
    InvoiceStatusID
)
GO

मुझे लगता है कि यह पत्ती के स्तर पर संग्रहीत किया जाता है, लेकिन यदि मूल्य को बरकरार नहीं रखा जाता है, तो कुछ भी कैसे संग्रहीत किया जाता है? इस स्थिति में SQL सर्वर को इन पंक्तियों को खोजने में सूचकांक कैसे मदद करता है?

किसी भी मदद की बहुत सराहना की,

बहुत धन्यवाद,

संपादित करें:

इसका जवाब देने के लिए ब्रेंट एंड आरोन का धन्यवाद, यहाँ PasteThePlan स्पष्ट रूप से दिखा रहा है कि उन्होंने क्या समझाया।


5
यह तालिका के डेटा पृष्ठों में नहीं है, लेकिन यह सूचकांक के पन्नों में कायम है ।
हारून बर्ट्रेंड

गैर निरंतर कंप्यूटेड स्तंभ तालिका में भौतिक रूप से संग्रहीत नहीं हैं। वे आभासी स्तंभ हैं। हर बार किसी क्वेरी में संदर्भित होने पर उनके मानों को पुनर्गठित किया जाता है। यह रेफरी देखें ।
परिजन शाह

जवाबों:


11

जब SQL सर्वर गणना किए गए क्षेत्र पर सूचकांक बनाता है, तो उस समय गणना किए गए फ़ील्ड को डिस्क पर लिखा जाता है - लेकिन केवल उस सूचकांक के 8K पृष्ठों पर। SQL सर्वर InvoiceStatusID की गणना कर सकता है क्योंकि यह संकुल सूचकांक के माध्यम से पढ़ता है - उस डेटा को संकुल सूचकांक में लिखने की कोई आवश्यकता नहीं है।

जैसा कि आप dbo.Invoice में पंक्तियों को हटाते / अद्यतन / सम्मिलित करते हैं, अनुक्रमित में डेटा अद्यतित रखा जाता है। (जब InvoiceStatus बदलता है, तो SQL सर्वर IX_Invoice को अपडेट करना भी जानता है।)

सबसे अच्छा तरीका है कि आप इसे अपने लिए देख सकते हैं वास्तव में यह करना है: इन ऑब्जेक्ट्स को बनाएं, और इनवॉइसस्टैटिड फ़ील्ड को छूने वाले अपडेट निष्पादित करें। निष्पादन योजना पोस्ट करें (PasteThePlan.com इसके लिए सहायक है) यदि आप यह देखना चाहते हैं कि सूचकांक अपडेट कहां हो रहे हैं।


1
@ Uberzen1 नहीं, जैसा कि उन्होंने बताया, यह इंडेक्स पेजों पर इन्सर्ट / अपडेट टाइम पर लिखा जाता है। यदि स्तंभ का उपयोग करने के लिए सूचकांक का उपयोग किया जाता है, तो इसे कुछ भी फिर से लिखना नहीं पड़ता है।
हारून बर्ट्रेंड

आह! मैं अब आपके साथ हूँ, क्षमा करें!
उबेरजन

6
@blobbles अच्छी तरह से, कोई अपराध नहीं है, लेकिन मुझे नहीं लगता कि यह ब्रेंट पर है। वे उसी XML को ड्रॉपबॉक्स, MSDN फ़ोरम में पेस्ट कर सकते हैं, यहाँ, मूल रूप से कहीं भी ऑनलाइन ... क्या हर ऑनलाइन सेवा को अब उन रहस्यों के लिए ज़िम्मेदार होने की ज़रूरत है जो उन लोगों द्वारा विभाजित किए जा सकते हैं जो वहां फाइलें अपलोड करते हैं?
हारून बर्ट्रेंड

2
@blobbles हाँ, आप बस लोगों को ओवरशेयरिंग से नहीं रोक सकते। हे, वैसे, मुझे इंस्टाग्राम पर फॉलो करो - मैं ब्रेंटो हूँ - और मैं अपने नाश्ते की तस्वीरें वहाँ साझा करती हूँ। ;-)
ब्रेंट ओजर

4
गोपनीयता लिंक में @blobbles, यह बताता है: आपके द्वारा यहां कॉपी / पेस्ट किया गया डेटा सार्वजनिक है । इसे कोई भी पढ़ सकता है। कोई सुरक्षा नहीं है।
ypercube y

8

एक अनुक्रमित, गैर-निरंतर कम्प्यूटेड कॉलम के लिए मूल्य तालिका के डेटा पृष्ठों में बरकरार नहीं है , लेकिन यह सूचकांक के पन्नों में बरकरार है । यह तालिका में गैर-स्थिर रहता है, भले ही यह 0, 1, या एकाधिक अनुक्रमित में बना रहे।

ब्रेंट के विवरण को स्पष्ट करने के लिए, आपने जो उदाहरण दिया है, आइए एक पंक्ति डालें:

INSERT dbo.Invoice(CustomerID, InvoiceStatus) VALUES(1,N'Sent');

अब, सूचकांक पृष्ठ देखें:

DBCC TRACEON(3604, -1);
DBCC IND(N'dbname', N'dbo.Invoice', 2);

(स्पष्ट रूप से बदलें dbname, और सूचकांक आईडी आपके मामले में 2 नहीं हो सकती है।)

आउटपुट (आपका निश्चित रूप से अलग होगा):

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

और अंत में, PageType2 पेज का निरीक्षण करते हैं :

DBCC PAGE(7, 1, 584, 3);

(आपको अपने डेटाबेस आईडी से मिलान करने के लिए 7 को बदलने की आवश्यकता होगी, और यदि आपके पास कई डेटा फ़ाइलें हैं, तो आपको PageFIDपहले परिणाम से मिलान करने के लिए दूसरे तर्क को बदलने की आवश्यकता हो सकती है ।)

आउटपुट:

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

वह इंडेक्स पेज पर है।


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

1
@ Uberzen1 क्या आप "वास्तविक परेशानी" को परिभाषित कर सकते हैं? क्या आप उस समस्या के बारे में एक प्रश्न पोस्ट करने जा रहे हैं ?
हारून बर्ट्रेंड

मैं कर सकता हूं, मैं इसे पहले कुछ और खुद खोदने जा रहा था, लेकिन बस अपने सिर को चारों ओर ले जाना चाहता था कि क्रिएट इंडेक्स स्टेटमेंट वास्तव में क्या कर रहा है। TLDR है; मेरे पास ऊपर की इनवॉइस टेबल के समान एक बड़ी टेबल है, इसमें लगभग 400 मीटर रिकॉर्ड हैं और दुर्भाग्य से इसके बीच में ऑर्डरस्टैटस कॉलम सही से थप्पड़ मारा गया है, जिससे इंडेक्सिंग आदि थोड़ा दर्दनाक हो गया है। हमने अभी के लिए एक संगणित कॉलम को जोड़ा है कि हम अंत में बने रहेंगे और वर्कर क्षेत्र को अपनी तालिका में बदल देंगे। 1/2
Uberzen1

5
@ Uberzen1 हाँ, क्योंकि गणना किए गए कॉलम को डिस्क पर वास्तव में अनुक्रमित करते समय लिखा जाता है, उस गतिविधि को लॉग इन करना होगा। गणना कॉलम पर निर्भरता को रोकने के लिए एक वर्कअराउंड हो सकता है - या तो उस अभिव्यक्ति को एक दृश्य या तदर्थ प्रश्नों में डाल दें, और यदि वह विकल्प नहीं है तो आप एक नया अशक्त स्तंभ बना सकते हैं, इसे चंक्स में अपडेट करें (लॉग की हत्या से बचने के लिए) , फिर गणना किए गए कॉलम को छोड़ें, नए कॉलम का नाम बदलें, और अपने DML को मैन्युअल रूप से लिखने के लिए बदलें। लेकिन वास्तव में चूंकि यह निरर्थक जानकारी है आप मौजूदा डेटा से प्राप्त कर सकते हैं, मैं पहले विकल्प का विकल्प चुनूंगा।
हारून बर्ट्रेंड

2
बहुत बहुत धन्यवाद हारून। मुझे खुशी है कि आपने इसके सामने एक दृश्य डालने का उल्लेख किया है क्योंकि यह मेरा समाधान भी था, शायद यह विचार फिर से लाने का समय है!
Uberzen1

7

PERSISTEDएक संगणित कॉलम की विशेषता यह है कि क्या मान तालिका (क्लस्टर इंडेक्स या हीप) में बने रहते हैं या नहीं और मान को इंडेक्स में बनाए रखा जाता है या नहीं।

CREATE INDEXअभिकलन कॉलम और अनुक्रमित से संबंधित सीमाएं के लिए आवश्यकताओं हैं:

गणना किए गए स्तंभ जो निर्धारक हैं और या तो सटीक या अव्यवस्थित हैं, कॉलम शामिल किए जा सकते हैं। इमेज, नेक्स्ट, टेक्स्ट, वर्चर (मैक्स), नार्चर (मैक्स), वर्बिनरी (मैक्स), और xml डेटा टाइप्स से लिए गए कंप्यूटेड कॉलम को गैर-कुंजी कॉलम में तब तक शामिल किया जा सकता है जब तक कि गणना किए गए कॉलम डेटा प्रकार शामिल के रूप में स्वीकार्य हो। स्तंभ। अधिक जानकारी के लिए, कम्प्यूटेड कॉलम पर अनुक्रमित देखें।

इस पर कोई सीमा नहीं है कि गणना किए गए कॉलम को कायम रखा गया है या नहीं।

और आगे (शामिल नहीं है लेकिन एक सूचकांक के मुख्य भाग में गणना किए गए स्तंभों के बारे में):

कंप्यूटेड कॉलम पर इंडेक्स बनाए जा सकते हैं। इसके अलावा, कंप्यूटेड कॉलम में संपत्ति हो सकती है PERSISTED। इसका अर्थ है कि डेटाबेस इंजन तालिका में गणना किए गए मानों को संग्रहीत करता है, और जब कोई अन्य कॉलम जिस पर गणना किए गए स्तंभ निर्भर होते हैं, उन्हें अपडेट किया जाता है। डेटाबेस इंजन इन निरंतर मूल्यों का उपयोग करता है, जब यह कॉलम पर एक इंडेक्स बनाता है, और जब किसी क्वेरी में इंडेक्स संदर्भित होता है।

एक गणना किए गए कॉलम को अनुक्रमित करने के लिए, गणना किए गए कॉलम को निश्चित और सटीक होना चाहिए। हालांकि, PERSISTEDसंपत्ति के उपयोग से शामिल करने के लिए अनुक्रमित गणना किए गए कॉलम के प्रकार का विस्तार होता है:

...

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