विशेष रूप से प्रदर्शन के बारे में, प्राथमिक कुंजी के रूप में GUID का उपयोग करने के लिए सर्वोत्तम अभ्यास क्या हैं?


336

मेरे पास एक एप्लिकेशन है जो लगभग सभी तालिकाओं में प्राथमिक कुंजी के रूप में GUID का उपयोग करता है और मैंने पढ़ा है कि प्राथमिक कुंजी के लिए GUID का उपयोग करते समय प्रदर्शन के बारे में समस्याएं हैं। ईमानदारी से, मैंने कोई समस्या नहीं देखी है, लेकिन मैं एक नया एप्लिकेशन शुरू करने वाला हूं और मैं अभी भी GUID को प्राथमिक कुंजी के रूप में उपयोग करना चाहता हूं, लेकिन मैं एक कंपोजिट प्राथमिक कुंजी (GUID) और शायद एक अन्य क्षेत्र का उपयोग करने के बारे में सोच रहा था। ।)

मैं एक GUID का उपयोग कर रहा हूं क्योंकि वे अलग-अलग परिवेश हैं जब आपके पास "उत्पादन", "परीक्षण" और "देव" डेटाबेस जैसे विभिन्न वातावरण हैं, और डेटाबेस के बीच प्रवास डेटा के लिए भी।

मैं डेटाबेस में सम्मिलित करने से पहले मैं एंटिटी फ्रेमवर्क 4.3 का उपयोग करूँगा और मैं आवेदन कोड में दिशा-निर्देश सौंपना चाहता हूँ। (यानी मैं एसक्यूएल गाइड उत्पन्न नहीं होने देना चाहता)।

GUID- आधारित प्राथमिक कुंजी बनाने के लिए सबसे अच्छा अभ्यास क्या है, ताकि इस दृष्टिकोण से जुड़े प्रदर्शन हिट से बचने के लिए?


20
मुद्दा नहीं माना जाता है। यदि आपका पीके क्लस्टर किया गया है तो लगभग हर इंसर्ट में पेज स्प्लिट होने की संभावना है। SQL सर्वर के आधुनिक संस्करणों में यह NEWSEQUENTIALID () के साथ "निश्चित" था, लेकिन यह पहले से गणना करने में सक्षम होने का लाभ खो देता है। मैं आपको कहीं और GUIDs पर पढ़ने की जोरदार सलाह देता हूं, क्योंकि यह एक व्यापक प्रश्न है और संभवतः एक धार्मिक लड़ाई को टाल देगा, जो घंटों तक चलेगा ...
हारून बर्ट्रेंड

4
मैं यह भी जोड़ूंगा कि सर्वर शब्द अस्पष्ट है मैं सर्वर साइड पर गाइड असाइन करना चाहता हूं (न ही SQL को GUID बनाने के लिए जाने देना चाहता हूं)
एरिक फिलिप्स

इस सवाल में इस "sql-server-guide-sort-एल्गोरिथम-क्यों" stackoverflow.com/questions/7810602/…
क्लिंटन वार्ड

जवाबों:


495

GUIDs आपकी प्राथमिक कुंजी के लिए एक स्वाभाविक पसंद हो सकता है - और यदि आपको वास्तव में चाहिए, तो आप संभवतः तालिका के प्राथमिक कुंजी के लिए इसका उपयोग करने का तर्क दे सकते हैं। जब तक मैं दृढ़ता से अनुशंसा नहीं करूँगा कि क्लस्टर कुंजी के रूप में GUID कॉलम का उपयोग करें , जो कि SQL सर्वर डिफ़ॉल्ट रूप से करता है, जब तक कि आप विशेष रूप से इसे नहीं बताते हैं।

आपको वास्तव में दो मुद्दों को अलग रखने की आवश्यकता है:

  1. प्राथमिक कुंजी एक तार्किक निर्माण है - उम्मीदवार कुंजी है जो विशिष्ट और मज़बूती से अपनी तालिका में प्रत्येक पंक्ति की पहचान करता है में से एक। यह कुछ भी हो सकता है, वास्तव में - INTGUID, ए, स्ट्रिंग - अपने परिदृश्य के लिए सबसे अधिक समझ में आता है।

  2. क्लस्टरिंग कुंजी (स्तंभ या स्तंभों कि मेज पर "संकुल अनुक्रमणिका" को परिभाषित) - यह एक है भौतिक भंडारण से संबंधित बात यहाँ है, और एक छोटे से, स्थिर, बढ़ती डेटा प्रकार अपने बेहतरीन पिकअप है - INTया BIGINTके रूप में अपने डिफ़ॉल्ट विकल्प।

डिफ़ॉल्ट रूप से, SQL सर्वर तालिका पर प्राथमिक कुंजी को क्लस्टरिंग कुंजी के रूप में भी उपयोग किया जाता है - लेकिन उस तरह से होने की आवश्यकता नहीं है! जब मैंने GUID-आधारित प्राथमिक / क्लस्टर कुंजी को दो अलग-अलग कुंजी - GUID पर प्राथमिक (तार्किक) कुंजी और एक अलग INT IDENTITY(1,1)कॉलम पर क्लस्टरिंग (ऑर्डरिंग) कुंजी को तोड़ते समय व्यक्तिगत रूप से बड़े पैमाने पर प्रदर्शन लाभ देखा है ।

जैसा कि किम्बर्ली ट्रिप - इंडेक्सिंग की रानी - और अन्य लोगों ने कई बार कहा है - GUIDजैसे कि क्लस्टरिंग कुंजी इष्टतम नहीं है, क्योंकि इसकी यादृच्छिकता के कारण, यह बड़े पैमाने पर पृष्ठ और सूचकांक विखंडन और आम तौर पर खराब प्रदर्शन को बढ़ावा देगा।

हाँ, मुझे पता है - newsequentialid()एसक्यूएल सर्वर 2005 और ऊपर में है - लेकिन यह भी सही मायने में और पूरी तरह से अनुक्रमिक नहीं है और इस तरह भी वही समस्याओं से ग्रस्त है GUID- बस थोड़ा कम प्रमुखता से।

फिर विचार करने के लिए एक और मुद्दा है: एक मेज पर क्लस्टरिंग कुंजी को प्रत्येक और प्रत्येक गैर-क्लस्टर इंडेक्स पर प्रत्येक प्रविष्टि के साथ-साथ आपकी तालिका में भी जोड़ा जाएगा - इस प्रकार आप वास्तव में यह सुनिश्चित करना चाहते हैं कि यह यथासंभव छोटा है। आमतौर पर, INTबड़ी संख्या में तालिकाओं के लिए 2+ बिलियन पंक्तियों के साथ पर्याप्त होना चाहिए - और GUIDक्लस्टरिंग कुंजी के रूप में तुलना करने पर , आप डिस्क पर और सर्वर मेमोरी में सैकड़ों मेगाबाइट भंडारण कर सकते हैं।

त्वरित गणना - INTबनाम GUIDप्राथमिक और क्लस्टरिंग कुंजी के रूप में उपयोग करना :

  • आधार तालिका 1'000'000 पंक्तियों (3.8 MB बनाम 15.26 MB) के साथ
  • 6 गैर-अनुक्रमित सूचकांक (22.89 एमबी बनाम 91.55 एमबी)

कुल: 25 एमबी बनाम 106 एमबी - और यह सिर्फ एक मेज पर है!

विचार के लिए कुछ और भोजन - किम्बर्ली ट्रिप द्वारा उत्कृष्ट सामान - इसे पढ़ें, इसे फिर से पढ़ें, इसे पचाएं! यह SQL सर्वर अनुक्रमण सुसमाचार है, वास्तव में।

पुनश्च: बेशक, अगर आप सिर्फ कुछ सौ या कुछ हजार पंक्तियों के साथ काम कर रहे हैं - तो इनमें से अधिकांश तर्कों का वास्तव में आप पर अधिक प्रभाव नहीं पड़ेगा। हालांकि: यदि आप दसियों या सैकड़ों हजारों पंक्तियों में आते हैं, या आप लाखों में गिनती शुरू करते हैं - तो उन बिंदुओं को समझना बहुत महत्वपूर्ण और बहुत महत्वपूर्ण हो जाता है।

अद्यतन: यदि आप अपने PKGUIDकॉलम को अपनी प्राथमिक कुंजी के रूप में रखना चाहते हैं (लेकिन आपकी क्लस्टरिंग कुंजी नहीं), और एक अन्य कॉलम MYINT( INT IDENTITY) आपकी क्लस्टरिंग कुंजी के रूप में है - तो इसका उपयोग करें:

CREATE TABLE dbo.MyTable
(PKGUID UNIQUEIDENTIFIER NOT NULL,
 MyINT INT IDENTITY(1,1) NOT NULL,
 .... add more columns as needed ...... )

ALTER TABLE dbo.MyTable
ADD CONSTRAINT PK_MyTable
PRIMARY KEY NONCLUSTERED (PKGUID)

CREATE UNIQUE CLUSTERED INDEX CIX_MyTable ON dbo.MyTable(MyINT)

मूल रूप से: आपको बस स्पष्ट रूप से PRIMARY KEYबाधा को बताना होगा कि यह NONCLUSTERED(अन्यथा यह आपके क्लस्टर इंडेक्स के रूप में बनाया गया है, डिफ़ॉल्ट रूप से) - और फिर आप एक दूसरा इंडेक्स बनाते हैं जिसे इस रूप में परिभाषित किया गया हैCLUSTERED

यह काम करेगा - और यह एक वैध विकल्प है यदि आपके पास एक मौजूदा प्रणाली है जिसे प्रदर्शन के लिए "फिर से इंजीनियर" होने की आवश्यकता है। एक नई प्रणाली के लिए, यदि आप स्क्रैच से शुरू करते हैं, और आप प्रतिकृति परिदृश्य में नहीं हैं, तो मैं हमेशा ID INT IDENTITY(1,1)अपनी क्लस्टर की गई प्राथमिक कुंजी के रूप में चुनूंगा - किसी भी चीज़ की तुलना में अधिक कुशल!


2
यह एक महान जवाब है, एक बात जिसका मैं उल्लेख करूंगा कि डालने से पहले कुंजी उत्पन्न करने में सक्षम होना अक्सर उपयोगी होता है। "न्यूट्रेडिशिअल ()" का उपयोग क्लस्टरिंग के साथ मदद कर सकता है, लेकिन इसके लिए SQL के लिए एक अतिरिक्त राउंड-ट्रिप की आवश्यकता होती है। तो "सरोगेट कुंजी" दृष्टिकोण का एक और लाभ यह है कि आप कम इंडेक्स विखंडन चिंताओं के साथ नई आईडी, क्लाइंट-साइड उत्पन्न कर सकते हैं।
एंड्रयू थाकेन

2
जिस तरह से मैंने इसे पढ़ा है वह यह है कि दोनों गैर-क्लस्टर किए गए अद्वितीय पहचानकर्ता स्तंभ और अंतर पहचान कॉलम, FK का अद्वितीय पहचानकर्ता होना चाहिए? यदि आप ऐसा करते हैं, तो आप वास्तव में सीधे पहचान कॉलम का उपयोग कब करेंगे, या आप नहीं करेंगे?
Pinkfloydx33

2
थोड़ा सवाल, क्या अब GUID को जॉइन या इंट आईडी पर इस्तेमाल किया जाना चाहिए? मेरी वृत्ति मुझे बताती है कि GUID का उपयोग किया जाना चाहिए, लेकिन मैं int id का उपयोग करके तकनीकी समस्या को देखने में विफल रहा ...
निकोलस बेल्ली

3
@marc_s लेकिन एक प्रतिकृति परिदृश्य में, यदि इंट कॉलम पहचान है, तो क्या हमें GUID का उपयोग नहीं करना चाहिए क्योंकि इंट कॉलम स्वयं को पूरे डिवाइस में दोहरा सकता है?
निकोलस बेली

6
@ किपकी: मुख्य मुद्दे हैं अगर आपके पास ऐसा प्राकृतिक मूल्य है - तो हां, आप इसे एक प्राथमिक कुंजी के रूप में उपयोग कर सकते हैं। लेकिन : DATETIMEउदाहरण के लिए मान किसी क्लस्टरिंग कुंजी के लिए उपयोगी नहीं हैं , क्योंकि उनके पास केवल 3.33ms सटीकता है, और इस प्रकार डुप्लिकेट मौजूद हो सकते हैं। तो ऐसे मामले में, आपको * अभी भीINT IDENTITY इसके बजाय की आवश्यकता है - इसलिए, मैं आमतौर पर डिफ़ॉल्ट रूप से उपयोग करता हूं, चूंकि मेरे 20+ वर्षों के अनुभव के बाद से, वास्तव में प्रयोग करने योग्य प्राकृतिक कुंजी शायद ही कभी मौजूद है ....
marc_s

51

मैं 2005 से पीके के रूप में GUID का उपयोग कर रहा हूं। इस वितरित डेटाबेस की दुनिया में, वितरित डेटा को मर्ज करने का यह सबसे अच्छा तरीका है। आप सम्मिलित तालिकाओं के पार मिलान की सभी चिंताओं के बिना मर्ज तालिकाओं को आग और भूल सकते हैं। GUIDs को बिना किसी चिंता के कॉपी किया जा सकता है।

GUID का उपयोग करने के लिए यह मेरा सेटअप है:

  1. पीके = गाइड। GUID को स्ट्रिंग्स के समान अनुक्रमित किया जाता है, इसलिए उच्च पंक्ति तालिकाओं (50 मिलियन से अधिक रिकॉर्ड) को तालिका विभाजन या अन्य प्रदर्शन तकनीकों की आवश्यकता हो सकती है। SQL सर्वर बेहद कुशल हो रहा है, इसलिए प्रदर्शन चिंताएं कम और कम लागू होती हैं।

  2. पीके गाइड एनओएन-क्लस्टर्ड इंडेक्स है। जब तक यह NewSequentialID न हो, कभी भी GUID को क्लस्टर इंडेक्स न करें। लेकिन फिर भी, एक सर्वर रिबूट ऑर्डर करने में बड़े ब्रेक का कारण बनेगा।

  3. हर तालिका में क्लस्टर Int जोड़ें। यह आपका अनुमानित सूचकांक है ... जो आपकी तालिका का आदेश देता है।

  4. ClusterIDs (int) में शामिल होना अधिक कुशल है, लेकिन मैं 20-30 मिलियन रिकॉर्ड तालिकाओं के साथ काम करता हूं, इसलिए GUIDs में शामिल होने से प्रदर्शन प्रभावित नहीं होता है। यदि आप अधिकतम प्रदर्शन चाहते हैं, तो ClusterID अवधारणा का उपयोग अपनी प्राथमिक कुंजी के रूप में करें और ClusterID पर शामिल हों।

यहाँ मेरी ईमेल तालिका है ...

CREATE TABLE [Core].[Email] (
    [EmailID]      UNIQUEIDENTIFIER CONSTRAINT [DF_Email_EmailID] DEFAULT (newsequentialid()) NOT NULL,        
    [EmailAddress] NVARCHAR (50)    CONSTRAINT [DF_Email_EmailAddress] DEFAULT ('') NOT NULL,        
    [CreatedDate]  DATETIME         CONSTRAINT [DF_Email_CreatedDate] DEFAULT (getutcdate()) NOT NULL,      
    [ClusterID] INT NOT NULL IDENTITY,
    CONSTRAINT [PK_Email] PRIMARY KEY NonCLUSTERED ([EmailID] ASC)
);
GO

CREATE UNIQUE CLUSTERED INDEX [IX_Email_ClusterID] ON [Core].[Email] ([ClusterID])
GO

CREATE UNIQUE NONCLUSTERED INDEX [IX_Email_EmailAddress] ON [Core].[Email] ([EmailAddress] Asc)

क्या आप PK_Email बाधा की व्याख्या कर सकते हैं? आपके पास ... NonClustered (EmailID ASC) के बजाय ... Nonclustered (ClusterID ASC) क्यों है?
फिल

2
बिलकुल। अनुक्रमित के साथ चल रही दो मुख्य बातें: 1. क्लस्टर पर क्लस्टर - डिस्क पर अपनी तालिका (0% विखंडन) का आदेश देता है। 2. ईमेल पर ग़ैर-संकुलित - GUID ID लुक्स को गति देने के लिए EmailID फ़ील्ड को अनुक्रमित करता है। एक GUID फ़ील्ड लुकअप स्ट्रिंग-ईश का व्यवहार करता है, इसलिए एक ई-मेल लुकअप इंडेक्स के बिना धीमा होगा।
रॉबर्ट जे। गुड

@ RobertJ.Good मैंने इस विधि को चर्चा करने से पहले देखा है यानी क्लस्टर पर एक सरोगेट इंट कुंजी जोड़ना। लेकिन मैं कहीं भी नहीं मिल सकता है जो एक ढेर का उपयोग करके एक सरोगेट कुंजी क्लस्टर इंडेक्स होने में प्रदर्शन लाभ दिखाता है। क्या आपके पास बेंचमार्क डेटा के लिए कोई लिंक है?
डेल के

1
Hi @DaleBurrell, तालिका विखंडन को रोकने के लिए क्लस्टर इंडेक्स है। प्रदर्शन लाभ तब होता है जब डिस्क विखंडन के क्रम में तालिका स्वाभाविक रूप से बढ़ती है, कम विखंडन के साथ।
राबर्ट जे। अच्छा

@ RobertJ.Good कि एक वेब अनुप्रयोग है? आप url / hrefs में क्या उपयोग कर रहे हैं? गाइड या इंट?
दरियाल

10

मैं वर्तमान में EF Core के साथ एक वेब एप्लिकेशन विकसित कर रहा हूं और यहां वह पैटर्न है जिसका मैं उपयोग करता हूं:

मेरी सभी कक्षाएं (टेबल) और एक इंट पीके और एफके। मुझे उस पर एक गैर-क्लस्टर किए गए अनुक्रमणिका के साथ टाइप गाइड (ग # कंस्ट्रक्टर द्वारा उत्पन्न) के साथ एक अतिरिक्त कॉलम मिला है।

EF के भीतर तालिका के सभी जोड़ इंट कुंजी के माध्यम से प्रबंधित किए जाते हैं जबकि बाहर से सभी (नियंत्रकों) का उपयोग गिड्स के साथ किया जाता है।

यह समाधान यूआरएल पर इंट कीज़ को नहीं दिखाने की अनुमति देता है लेकिन मॉडल को सुव्यवस्थित और तेज़ बनाए रखता है।


क्या पूर्णांक के रूप में पूर्णांक पीके को कॉन्फ़िगर करने के लिए आपको कुछ करने की आवश्यकता है, जैसे डेटा एनोटेशन, या क्या यह स्वचालित रूप से कॉन्फ़िगर किया गया है?
एलन वैंग

गाइड एक के लिए आप किस संपत्ति का नाम इस्तेमाल करते हैं?
ट्रोंग फान

3

यदि आप GUID को प्राथमिक कुंजी के रूप में उपयोग करते हैं और क्लस्टर इंडेक्स बनाते हैं, तो मेरा सुझाव है कि इसके लिए NEWSEQUENTIALID () मान का उपयोग करें


तुम ऐसा क्यों करोगे?
जेनुअफफा

3

यह लिंक कहता है कि मैं अपने निर्णय लेने में मदद कर सकता हूं। मैं आमतौर पर एक प्राथमिक कुंजी के रूप में एक इंट का विकल्प चुनता हूं, जब तक कि मुझे विशिष्ट आवश्यकता न हो और मैं SQL सर्वर को इस क्षेत्र को स्वतः उत्पन्न / बनाए रखने देता हूं जब तक कि मेरे पास कुछ विशिष्ट कारण न हो। वास्तव में, प्रदर्शन संबंधी चिंताओं को आपके विशिष्ट ऐप के आधार पर निर्धारित किया जाना चाहिए। यहाँ पर खेलने के कई कारक हैं, लेकिन अपेक्षित db आकार, उचित अनुक्रमण, कुशल क्वेरी और अधिक तक सीमित नहीं हैं। यद्यपि लोग असहमत हो सकते हैं, मुझे लगता है कि कई परिदृश्यों में आपको या तो विकल्प के साथ अंतर दिखाई नहीं देगा और आपको यह चुनना चाहिए कि आपके ऐप के लिए क्या अधिक उपयुक्त है और क्या आपको आसान, त्वरित और अधिक प्रभावी रूप से विकसित करने की अनुमति देता है (यदि आप ऐप को कभी पूरा नहीं करते हैं। बाकी क्या फर्क पड़ता है :)।

https://web.archive.org/web/20120812080710/http://databases.aspfaq.com/database/what-should-i-choose-for-my-primary-key.html

PS मुझे यकीन नहीं है कि आप कम्पोजिट पीके का उपयोग क्यों करेंगे या आपको क्या फायदा होगा जो आपको विश्वास दिलाता है।


पूर्णतया सहमत!! लेकिन इसका मतलब यह है कि अगर मेरे पास पीके के रूप में एक GUID है या GUID और अन्य क्षेत्र के साथ समग्र PK समान अधिकार होने जा रहा है?
VAAA

1
पीके (इंडेक्स) दो स्तंभों से बना होगा, लेकिन जब तक आपके पास ऐसा करने के लिए कुछ विशेष कारण नहीं है, यह अनावश्यक लगता है।
मैट मैट

1
BTW यह सवाल वहाँ सबसे ध्रुवीकरण और बहस किए गए प्रश्नों में से एक है और इसलिए इसके लिए एक उत्तर प्राप्त करना बेहद मुश्किल है कि आप इसके साथ 100% सहज महसूस करेंगे। या तो विधि व्यापार-नापसंद के साथ आती है, इसलिए शुभकामनाएं :)
मैट

1

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

  1. https://www.sqlskills.com/blogs/kimberly/disk-space-is-cheap/
  2. https://www.sqlskills.com/blogs/kimberly/guids-as-primary-keys-andor-the-clustering-key/

0

अनुक्रमिक आईडी होने से यह आपकी साइट और डेटा से समझौता करने के लिए किसी हैकर या डेटा खनिक के लिए बहुत आसान है। वेबसाइट के लिए पीके चुनते समय ध्यान रखें।


क्या आप इस दावे का समर्थन करने के लिए कोई तर्क या सबूत प्रदान कर सकते हैं? मैं यह देखने के लिए संघर्ष कर रहा हूं कि कैसे एक अनुक्रमिक आईडी सुरक्षा से समझौता कर सकती है।
जोंगलोन

यकीन है, अगर आपको पता है कि आईडी नंबर पूर्णांक हैं, तो आप डीबी में क्रमिक रिकॉर्ड का अनुमान लगा सकते हैं। इसलिए यदि आप किसी एकल आइटम को क्वेरी करते हैं, तो आप कह सकते हैं कि अगला आइटम pk + 1 है। यदि आपके पास यादृच्छिक GUIDS है, तो यह एक पैटर्न का पालन नहीं करेगा। आपके द्वारा पहले बताए गए (और PK को जानें) की तुलना में अन्य रिकॉर्ड को क्वेरी करना लगभग असंभव होगा।
डब्लू

1
यदि कोई हैकर आपके डेटाबेस से पहले से ही समझौता कर सकता है, तो मैं यह देखने में विफल रहता हूं कि अनुक्रमिक आईडी कैसे स्थिति को बदतर बनाती है।
जोनागलन

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

2
आप वेब पेज पर रिकॉर्ड खोजने के लिए GUID का उपयोग कर सकते हैं, जो तालिका का PK नहीं है। किसी वेबसाइट में क्वेरी पैरामीटर का उपयोग यह परिभाषित नहीं करना चाहिए कि आप अपने DB स्कीमा की संरचना कैसे करते हैं। पीके का यूआई या बैकएंड सिस्टम में इनपुट और मापदंडों से कोई लेना-देना नहीं है।
पैनोस रॉडीटाकिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.