प्राथमिक कुंजी के रूप में GUID के साथ डेटाबेस डिजाइन को ठीक करने का सबसे अच्छा समाधान


18

मैं इस विचार की कुछ पुष्टि के बाद हूं कि यदि कोई एक है तो एक खराब प्रदर्शन करने वाले डेटाबेस या बेहतर सुझाव को ठीक करने के लिए। हमेशा बेहतर सुझावों के लिए खुला।

मेरे पास एक बहुत बड़ा डेटाबेस है (20+ मिलियन रिकॉर्ड प्रतिदिन लगभग 1/2 मिलियन से बढ़ रहा है) जो GUID को PK के रूप में उपयोग कर रहे हैं।

मेरे हिस्से पर एक निगरानी लेकिन पीके SQL सर्वर पर क्लस्टर किया गया है और प्रदर्शन समस्याओं का कारण बन रहा है।

एक गाइड का कारण - यह डेटाबेस 150 अन्य डेटाबेस के साथ आंशिक रूप से सिंक्रनाइज़ है इसलिए पीके को अद्वितीय होने की आवश्यकता है। सिंक्रनाइज़ेशन SQL सर्वर द्वारा प्रबंधित नहीं किया जाता है, बल्कि एक कस्टम प्रक्रिया का निर्माण होता है जो सिस्टम की आवश्यकताओं के लिए डेटा को सिंक में रखता है - यह सब उस GUID पर आधारित है।

150 दूरस्थ डेटाबेस में से प्रत्येक केंद्रीय SQL डेटाबेस में संग्रहीत के रूप में पूर्ण डेटा संग्रहीत नहीं करता है। वे केवल उन डेटा का एक सबसेट संग्रहीत करते हैं जिनकी उन्हें वास्तव में आवश्यकता होती है, और डेटा की आवश्यकता उनके लिए अद्वितीय नहीं होती है (150 डेटाबेस में से 10 में अन्य साइटों के डेटाबेस से कुछ समान रिकॉर्ड हो सकते हैं उदाहरण के लिए - वे साझा करते हैं)। इसके अलावा - डेटा वास्तव में दूरस्थ साइटों पर उत्पन्न होता है - केंद्रीय बिंदु पर नहीं - इसलिए GUIDs की आवश्यकता।

केंद्रीय डेटाबेस का उपयोग न केवल सब कुछ सिंक में रखने के लिए किया जाता है, बल्कि 3000 + उपयोगकर्ताओं के प्रश्नों को उस बहुत बड़े खंडित डेटाबेस के खिलाफ निष्पादित किया जाएगा। शुरुआती परीक्षण में यह एक बड़ी समस्या है।

सौभाग्य से हम अभी तक जीवित नहीं हैं - इसलिए मैं बदलाव कर सकता हूं और आवश्यकता होने पर चीजों को ऑफलाइन ले सकता हूं जो कम से कम कुछ है।

दूरस्थ डेटाबेस का प्रदर्शन कोई समस्या नहीं है - डेटा सबसेट बहुत छोटा है और डेटाबेस आमतौर पर कुल आकार में 1GB से ऊपर कभी नहीं मिलता है। अभिलेखों को मुख्य प्रणाली में वापस नियमित रूप से खिलाया जाता है और छोटे बीडी से निकाल दिया जाता है जब आवश्यकता नहीं होती है।

केंद्रीय डीबी का प्रदर्शन जो सभी रिकॉर्डों का रक्षक है, वह कई रिकॉर्ड्स के लिए एक प्राथमिक कुंजी के रूप में क्लस्टर किए गए GUID के कारण - बहुत ही कम है। सूचकांक विखंडन चार्ट से दूर है।

इसलिए - प्रदर्शन के मुद्दे को ठीक करने के लिए मेरे विचार एक नया कॉलम बनाने के लिए है - अनसाइन्ड बिज़ेंट आइडेंटिटी (1,1) और फिर टेबल बिगन कॉलम के क्लस्टर्ड पीके को बदलें।

मैं GUID फ़ील्ड पर एक विशिष्ट नॉन क्लस्टर्ड इंडेक्स बनाऊंगा जो प्राथमिक कुंजी थी।

छोटे दूरस्थ 150 डेटाबेस को सेंट्रल SQL सर्वर डेटाबेस पर नए पीके के बारे में जानने की आवश्यकता नहीं है - इसका शुद्ध रूप से डेटाबेस में डेटा को व्यवस्थित करने और खराब प्रदर्शन और विखंडन को रोकने के लिए उपयोग किया जाएगा।

क्या यह काम करेगा और केंद्रीय एसक्यूएल डेटाबेस के प्रदर्शन में सुधार करेगा और भविष्य के सूचकांक विखंडन नरक (निश्चित रूप से एक हद तक) को रोक देगा? या क्या मुझे यहाँ बहुत कुछ याद आया है जो कूद कर मुझे काट रहा है और इससे भी अधिक दुःख का कारण है?


2
@mattytommo मैं सहमत हूँ।
पॉल फ्लेमिंग

2
क्या आप सप्ताह में कम से कम एक बार सूचकांक डीफ़्रैग्मेन्टेशन कर रहे हैं ?
एंडोमर

1
क्या आपके पास क्लस्टर करने के लिए सार्थक कुछ भी है? यानी, कौन सी क्वेरी तेज़ होनी चाहिए? यह निश्चित रूप से गाइड पर रेंज स्कैन नहीं होने जा रहा है, इसलिए केवल एक ऑटोइन्क्रिमेंट चुनने के बजाय, विचार करें कि क्या कुछ क्वेरी-टाइम इष्टतम क्लस्टरिंग है जिसे आप चुन सकते हैं। यदि नहीं, तो आगे बढ़ो और bigint का उपयोग करें

2
@ बोरिक एक महान विचार नहीं है, जो उसके पास है और उसकी विकास दर के आधार पर, वह int4255 दिनों (11.5 वर्ष) में समाप्त हो जाएगा । अगर उसने ऐसा किया, तो वह आपको केवल 11.5 साल में दोषी
ठहराएगा

1
एक विपरीत दृष्टिकोण: आपको क्यों लगता है कि GUID डेटाटाइप एक मुद्दा है? यह 128-बिट पूर्णांक है। आपको क्या लगता है कि इसे 64-बिट पूर्णांक (bigint) या 32-बिट पूर्णांक (int) के साथ प्रतिस्थापित करने से गति में ध्यान देने योग्य अंतर होने वाला है? मुझे लगता है कि आपको निश्चित रूप से क्लस्टरिंग कुंजी को किसी और चीज़ में बदलना चाहिए, ताकि विखंडन की ओर ले जाने वाले सभी पृष्ठ विभाजन से बचा जा सके, लेकिन मुझे नहीं लगता कि आपको डेटाटाइप को बदलना चाहिए जब तक कि आप यह सुनिश्चित न कर लें कि डेटाटाइप समस्या है।
ग्रीनस्टोन वाकर

जवाबों:


8

आपको निश्चित रूप से GUID पर क्लस्टर करने की आवश्यकता नहीं है। यदि आपके पास ऐसा कुछ है जो आपको उस GUID के अलावा अन्य विशिष्ट रिकॉर्डों की पहचान करने की अनुमति देगा , तो मेरा सुझाव है कि आप उस अन्य क्षेत्र पर एक अद्वितीय सूचकांक बनाने और उस सूचकांक को क्लस्टर बनाने के लिए देखें। यदि नहीं, तो आप अन्य क्षेत्रों पर भी क्लस्टर करने के लिए स्वतंत्र हैं, यहां तक ​​कि नॉनिक इंडेक्स का भी उपयोग कर सकते हैं। हालाँकि, क्लस्टर का दृष्टिकोण आपके डेटा को विभाजित करने और क्वेरी करने की सबसे अच्छी सुविधा होगी - इसलिए, यदि आपको "क्षेत्र" फ़ील्ड, या कुछ और मिला है, जो आपकी क्लस्टरिंग योजना के लिए एक उम्मीदवार हो सकता है।

BIGINTअन्य डेटाबेस से डेटा को जोड़ने और केंद्रीय स्टोर में अपने डेटाबेस को एकीकृत करने के लिए परिवर्तन के साथ समस्या होगी। यदि यह एक विचार नहीं है - और कभी भी विचार नहीं होगा - तो, ​​हाँ, BIGINTसूचकांक के पुनर्वित्त मुद्दे को अच्छी तरह से हल करेगा।

दृश्यों के पीछे, यदि आप एक क्लस्टर इंडेक्स निर्दिष्ट नहीं करते हैं, तो SQL सर्वर एक ही काम करता है: यह एक पंक्ति आईडी फ़ील्ड बनाता है और उस में अन्य सभी इंडेक्स को मैप करता है। इसलिए, इसे स्वयं करके, आप इसे हल कर रहे हैं जैसे SQL इसे हल करेगा।


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

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

तो मुझे लगता है कि अगर मुझे लगता है कि अगर मैं BIGINT क्लस्टर्ड PK को नहीं करता हूं, और PK को नॉन-क्लस्टर किए गए GUID में नहीं बदलता हूं, तो प्रदर्शन के निहितार्थ क्या हैं? मेज पर अन्य गैर-संकुल सूचकांक हैं जिन्हें अक्सर खोजा जाएगा। क्या यह उन खोजों के प्रदर्शन पर प्रभाव डालेगा?
रॉडल्स

+1 मैं GUID के साथ बने रहने का सुझाव भी दूंगा। वितरित प्रणालियों में उन्हें बदलना बहुत कठिन है। आपका बड़ा टेबल क्लस्टर्ड इंडेक्स इस बात पर आधारित होना चाहिए कि आप डेटा की क्वेरी कैसे करते हैं ।
रेमस रुसानु

1
हाय दोस्तों - बस एक अद्यतन - मैंने संशोधनों को बनाया और पीके को GUID पर एक गैर-संकुलित कर दिया और SQL सर्वर डेटाबेस में 2+ मिलियन रिकॉर्ड डालने में व्यस्त है। एक ही समय में डेटा डाला जा रहा था, मैं जानकारी के लिए डेटाबेस को क्वेरी करने में सक्षम था और प्रश्नों से पहले जो कि 10 मिनट में समय समाप्त हो गया था, 1-2 सेकंड के मामले में पूरा हुआ। इसलिए - पीके को नॉन क्लस्टर्ड बना दिया और बिगनेट के बारे में चिंता न करते हुए लगता है कि उन्होंने अच्छी तरह से काम किया है। सभी के इनपुट और सहायता के लिए बहुत धन्यवाद।
रोड्डल्स

1

यह एक लंबा आदेश है।

मुझे एक मध्यम आदमी दृष्टिकोण का सुझाव दें।

मैं System.Guid.NewGuid () यादृच्छिक छापे उत्पन्न कर रहा था। (मैं ग्राहक को एक अनुक्रमिक बनाने के लिए डेटाबेस पर निर्भर होने के बजाय, अपना खुद का गाइड बनाने की अनुमति दे रहा था)।

एक बार जब मैं क्लाइंट पक्ष पर एक UuidCreateSequential ले गया, तो मेरा प्रदर्शन बेहतर हो गया, विशेषकर INERTERT पर।

यहाँ डॉटनेट क्लाइंट कोड वूडू है। मुझे यकीन है कि मैं कहीं न कहीं से नाराज हूँ:

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;


namespace MyCompany.MyTechnology
{
  public static class Guid
  {


    [DllImport("rpcrt4.dll", SetLastError = true)]
    static extern int UuidCreateSequential(out System.Guid guid);


    public static System.Guid NewGuid()
    {
      return CreateSequentialUUID();
    }


    public static System.Guid CreateSequentialUUID()
    {
      const int RPC_S_OK = 0;
      System.Guid g;
      int hr = UuidCreateSequential(out g);
      if (hr != RPC_S_OK)
        throw new ApplicationException("UuidCreateSequential failed: " + hr);
      return g;
    }


  }
}














    /*

Original Reference for Code:
http://www.pinvoke.net/default.aspx/rpcrt4/UuidCreateSequential.html


*/

/*



Text From URL above:

UuidCreateSequential (rpcrt4)

Type a page name and press Enter. You'll jump to the page if it exists, or you can create it if it doesn't.
To create a page in a module other than rpcrt4, prefix the name with the module name and a period.
. Summary
Creates a new UUID 
C# Signature:
[DllImport("rpcrt4.dll", SetLastError=true)]
static extern int UuidCreateSequential(out Guid guid);


VB Signature:
Declare Function UuidCreateSequential Lib "rpcrt4.dll" (ByRef id As Guid) As Integer


User-Defined Types:
None.

Notes:
Microsoft changed the UuidCreate function so it no longer uses the machine's MAC address as part of the UUID. Since CoCreateGuid calls UuidCreate to get its GUID, its output also changed. If you still like the GUIDs to be generated in sequential order (helpful for keeping a related group of GUIDs together in the system registry), you can use the UuidCreateSequential function.

CoCreateGuid generates random-looking GUIDs like these:

92E60A8A-2A99-4F53-9A71-AC69BD7E4D75
BB88FD63-DAC2-4B15-8ADF-1D502E64B92F
28F8800C-C804-4F0F-B6F1-24BFC4D4EE80
EBD133A6-6CF3-4ADA-B723-A8177B70D268
B10A35C0-F012-4EC1-9D24-3CC91D2B7122



UuidCreateSequential generates sequential GUIDs like these:

19F287B4-8830-11D9-8BFC-000CF1ADC5B7
19F287B5-8830-11D9-8BFC-000CF1ADC5B7
19F287B6-8830-11D9-8BFC-000CF1ADC5B7
19F287B7-8830-11D9-8BFC-000CF1ADC5B7
19F287B8-8830-11D9-8BFC-000CF1ADC5B7



Here is a summary of the differences in the output of UuidCreateSequential:

The last six bytes reveal your MAC address 
Several GUIDs generated in a row are sequential 
Tips & Tricks:
Please add some!

Sample Code in C#:
static Guid UuidCreateSequential()
{
   const int RPC_S_OK = 0;
   Guid g;
   int hr = UuidCreateSequential(out g);
   if (hr != RPC_S_OK)
     throw new ApplicationException
       ("UuidCreateSequential failed: " + hr);
   return g;
}



Sample Code in VB:
Sub Main()
   Dim myId As Guid
   Dim code As Integer
   code = UuidCreateSequential(myId)
   If code <> 0 Then
     Console.WriteLine("UuidCreateSequential failed: {0}", code)
   Else
     Console.WriteLine(myId)
   End If
End Sub




*/

अलग पहचान:

यदि आपका मुख्य db और रिमोट db "जुड़े हुए हैं" (जैसा कि, sp_linkserver) ...... तो आप "duid जनरेटर" के रूप में मुख्य db का उपयोग कर सकते हैं।

आप uuid का "एक-एक करके" प्राप्त नहीं करना चाहते हैं, यह बहुत अधिक चैटिंग है।

लेकिन आप uuid का सेट ले सकते हैं।

नीचे कुछ कोड दिए गए हैं:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id =
 OBJECT_ID(N'[dbo].[uspNewSequentialUUIDCreateRange]') AND type in (N'P',
 N'PC'))

 DROP PROCEDURE [dbo].[uspNewSequentialUUIDCreateRange]

 GO



 CREATE PROCEDURE [dbo].[uspNewSequentialUUIDCreateRange] (

 @newUUIDCount int --return

 )

 AS

 SET NOCOUNT ON

 declare @t table ( dummyid int , entryid int identity(1,1) , uuid
 uniqueidentifier default newsequentialid() )

 insert into @t ( dummyid ) select top (@newUUIDCount) 0 from dbo.sysobjects
 so with (nolock)

 select entryid , uuid from @t

 SET NOCOUNT OFF

 GO

/ *

--START TEST

 set nocount ON

 Create Table #HolderTable (entryid int , uuid uniqueidentifier )

 declare @NewUUIDCount int

 select @NewUUIDCount = 20

 INSERT INTO #HolderTable EXEC dbo.uspNewSequentialUUIDCreateRange
 @NewUUIDCount

 select * from #HolderTable

 DROP Table #HolderTable

 --END TEST CODE

* /


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

क्या 150 "दूरस्थ" डेटाबेस एक बार में एक सम्मिलित कर रहे हैं? या वे रात में या कुछ और थोक में डेटा स्थानांतरित कर रहे हैं? तो तुम एक चट्टान और कठिन जगह के बीच थोड़े हो। Bigint का उपयोग करना अंततः कमरे से बाहर चला जाएगा (शायद) और आपको अभी भी कई डीबी के पार अद्वितीय मूल्य प्राप्त करना है। तो यहाँ मेरा कट्टरपंथी विचार है। क्या 150 रिमोट डेटाबेस उनके UUID को केंद्रीय सेवा से प्राप्त कर सकते हैं? यह एक विचार है। क्या 150 दूरस्थ डेटाबेस मुख्य डेटाबेस में "लिंक्ड" (sp_addlinkedserver के रूप में) हैं? फिर मेरे पास एक यूडीएफ है जिस पर विचार किया जा सकता है। मुझे देखने दो कि क्या मुझे मिल सकता है।
ग्रेनडाकोडर

यहाँ एक लेख है जो अनुक्रमिक के बारे में बात करता है (जो मैं पहले से ही लिखा था उससे संबंधित नहीं है, मुझे लगता है कि इसकी दिलचस्प है) codeproject.com/Articles/388157/…
granadaCoder

0

अपने विवरण के आधार पर, BIGINT के साथ जाएं। हालांकि, GUID के लिए सूचकांक गैर-अद्वितीय हो सकता है, क्योंकि GUID को वैसे भी विश्व स्तर पर अद्वितीय माना जाता है।


-1

यदि GUID को ठीक से संग्रहीत किया जाता है, तो अद्वितीय पहचानकर्ता के पास कोई भी प्रदर्शन समस्याएँ नहीं होनी चाहिए ... और यदि आप अनुक्रमिक GUID का बेहतर उपयोग कर सकते हैं ...

इसके अलावा @mattytommo INT का उपयोग करने के साथ 11.5 साल के बारे में अच्छी बात है ...


हाँ - लेकिन गाइड SQL सर्वर डेटाबेस पर नहीं, बल्कि दूरस्थ 150 डेटाबेस में उत्पन्न होता है, इसलिए मैं क्रमिक उपयोग नहीं कर सकता - लेकिन प्रतिक्रिया के लिए धन्यवाद।
रोड्डल्स

उस स्थिति में, मेरी राय में आपकी योजना एक ध्वनि है, मैंने डीबी में से एक पर इसी तरह का काम किया है जिसे मैं प्रबंधित करता हूं, मैंने एक INT DENTITY (1,1) बनाई और इसे क्लस्टर पीके और साथ ही डेटा के लिए मानवीय पठनीय पहचानकर्ता के रूप में सेट किया। पुल अप करें और मैंने GUID (अनुक्रमणिका) को ट्रैकर के रूप में रखा जहां वह उत्पन्न हो सके। लेकिन मेरी प्रेरणा अंतरिक्ष की बचत से अधिक थी ...
बोरिक

आपके उत्तर और अंतर्दृष्टि के लिए बहुत धन्यवाद और बहुत कुछ। :)
रोड्डल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.