हालांकि यह पोस्ट जानकारी की कमी के कारण पूर्ण उत्तर नहीं होगी, यह आपको उचित दिशा में इंगित करने में सक्षम होना चाहिए या अन्यथा अंतर्दृष्टि प्राप्त करना चाहिए जिसे आप बाद में समुदाय के साथ साझा कर सकते हैं।
दुर्भाग्य से, इस परिभाषा के परिणामस्वरूप डिस्क-आधारित तालिका के साथ पिछली स्थिति के संबंध में प्रदर्शन में गिरावट आई है। परिमाण का क्रम कम से कम 10% अधिक है (कि कुछ मामलों में 100% तक पहुंच जाता है, इसलिए दोहरा समय)।
सबसे अधिक, मैं Microsoft द्वारा विज्ञापित लॉक-फ्री आर्किटेक्चर को देखते हुए उच्च-संगामिति परिदृश्यों में सुपर-लाभ प्राप्त करने की उम्मीद कर रहा था। इसके बजाय, सबसे खराब प्रदर्शन तब होता है जब कई समवर्ती उपयोगकर्ता टेबल पर कई प्रश्न चला रहे होते हैं।
यह परेशान करने वाला है क्योंकि यह निश्चित रूप से नहीं होना चाहिए। कुछ कार्यभार मेमोरी टेबल (SQL 2014) के लिए नहीं हैं और कुछ कार्यभार इसके लिए स्वयं को उधार देते हैं। ज्यादातर स्थितियों में केवल माइग्रेट करके और उचित अनुक्रमित चुनकर प्रदर्शन में न्यूनतम गिरावट हो सकती है।
मूल रूप से मैं इस बारे में आपके सवालों के बारे में बहुत सोच रहा था:
प्रशन:
- सही BUCKET_COUNT सेट करने के लिए क्या है?
- मुझे किस तरह के सूचकांक का उपयोग करना चाहिए?
- डिस्क-आधारित तालिका के साथ प्रदर्शन खराब क्यों हैं?
शुरू में मेरा मानना था कि मेमोरी टेबल और इंडेक्स में वास्तविक नहीं होने के साथ एक मुद्दा होना चाहिए। जबकि मेमोरी ऑप्टिमाइज़्ड हैश इंडेक्स परिभाषा के साथ कुछ मुद्दे हैं, मेरा मानना है कि असली मुद्दा उपयोग किए गए प्रश्नों के साथ होना चाहिए।
-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
SELECT @fixedValue, id2, col1, col2 FROM AnotherTable
यह आवेषण अत्यंत तेज़ होना चाहिए अगर यह केवल मेमोरी टेबल में शामिल हो। हालाँकि, इसमें डिस्क आधारित तालिका भी शामिल है और यह सभी लॉकिंग और ब्लॉकिंग से संबंधित है। इस प्रकार, डिस्क टाइम टेबल पर यहां वास्तविक समय की बर्बादी होती है।
जब मैंने मेमोरी में डेटा लोड करने के बाद डिस्क आधारित तालिका से 100,000 पंक्ति सम्मिलित के खिलाफ एक त्वरित परीक्षण किया था - यह सब-सेकंड प्रतिक्रिया समय था। हालाँकि, आपका अधिकांश डेटा केवल बहुत कम समय के लिए रखा जाता है, 20 सेकंड से कम। यह वास्तव में कैश में रहने के लिए बहुत समय नहीं देता है। इसके अतिरिक्त मैं अनिश्चित हूं कि AnotherTable
वास्तव में कितना बड़ा है और यह नहीं जानता कि क्या मूल्यों को डिस्क से पढ़ा जा रहा है या नहीं। हमें इन उत्तरों के लिए आप पर निर्भर रहना होगा।
क्वेरी का चयन करें:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1
फिर, हम इंटरॉप + डिस्क आधारित टेबल प्रदर्शन की दया पर हैं। इसके अतिरिक्त, एचएएसएच इंडेक्स पर सॉर्ट सस्ते नहीं हैं और एक गैर-अनुक्रमित इंडेक्स का उपयोग किया जाना चाहिए। इसे इंडेक्स गाइड में कहा जाता है जो मैं टिप्पणियों में जुड़ा हुआ हूं।
कुछ वास्तविक शोध आधारित तथ्य देने के लिए, मैंने SearchItems
मेमोरी टेबल को 10 मिलियन पंक्तियों के AnotherTable
साथ और 100,000 के साथ लोड किया क्योंकि मुझे इसके वास्तविक आकार या आँकड़ों की जानकारी नहीं थी। फिर मैंने निष्पादित करने के लिए ऊपर दी गई क्वेरी का उपयोग किया। इसके अतिरिक्त मैंने Wait_completed पर एक विस्तारित ईवेंट सत्र बनाया और इसे रिंग बफर में डाल दिया। प्रत्येक रन के बाद इसे साफ किया गया था। मैं DBCC DROPCLEANBUFFERS
एक ऐसे वातावरण का अनुकरण करने के लिए भी दौड़ा, जहाँ सभी डेटा स्मृति निवासी नहीं हो सकते हैं।
निर्वात में देखने पर परिणाम कुछ भी शानदार नहीं थे। चूँकि मैं जिस लैपटॉप पर यह परीक्षण कर रहा हूँ, वह उच्च श्रेणी के SSD का उपयोग कर रहा है, मैंने कृत्रिम रूप से VM के लिए डिस्क आधारित प्रदर्शन को चालू कर दिया है।
परिणाम केवल इन-मेमोरी आधारित तालिका पर क्वेरी के 5 रन के बाद बिना किसी प्रतीक्षा जानकारी के साथ आए (सम्मिलित और कोई उप-क्वेरी को हटाकर)। यह उम्मीद के मुताबिक बहुत ज्यादा है।
मूल क्वेरी का उपयोग करते समय, हालांकि, मेरे पास इंतजार था। इस मामले में यह PAGEIOLATCH_SH था जो समझ में आता है क्योंकि डेटा डिस्क से पढ़ा जा रहा है। चूंकि मैं इस प्रणाली का एकमात्र उपयोगकर्ता हूं और आवेषण, अपडेट के लिए बड़े पैमाने पर परीक्षण वातावरण बनाने के लिए समय नहीं बिताया है, इसलिए इसमें शामिल होने वाली तालिका के खिलाफ हटाए जाने से मुझे कोई लॉकिंग या अवरुद्ध होने की उम्मीद नहीं थी।
इस मामले में, एक बार फिर, डिस्क आधारित तालिका पर समय का महत्वपूर्ण हिस्सा खर्च किया गया था।
अंत में डिलीट क्वेरी। सिर्फ ID1 पर आधारित पंक्तियों को खोजना किसी इंडेक्स के साथ बेहद कुशल नहीं है। हालांकि यह सच है कि समानता की भविष्यवाणी है कि हैश इंडेक्स उचित हैं, जिस बाल्टी में डेटा गिरता है वह संपूर्ण हैशेड कॉलम से आधारित होता है। इस प्रकार id1, id2 जहां id1 = 1, id2 = 2, और id1 = 1, id2 = 3 अलग-अलग बाल्टियों में हैश होगा क्योंकि हैश उस पार (1,2) और (1,3) होगा। यह एक साधारण बी-ट्री रेंज स्कैन नहीं होगा क्योंकि हैश इंडेक्स को उसी तरह संरचित नहीं किया जाता है। मैं तब इस ऑपरेशन के लिए आदर्श सूचकांक नहीं होने की उम्मीद करूंगा, हालांकि मैं यह उम्मीद नहीं करूंगा कि यह लंबे समय तक अनुभव के रूप में आदेश ले। मुझे इस पर इंतज़ार_इनफो देखने में दिलचस्पी होगी।
सबसे अधिक, मैं Microsoft द्वारा विज्ञापित लॉक-फ्री आर्किटेक्चर को देखते हुए उच्च-संगामिति परिदृश्यों में सुपर-लाभ प्राप्त करने की उम्मीद कर रहा था। इसके बजाय, सबसे खराब प्रदर्शन तब होता है जब कई समवर्ती उपयोगकर्ता टेबल पर कई प्रश्न चला रहे होते हैं।
हालांकि यह सच है कि लॉज का उपयोग तार्किक स्थिरता के लिए किया जाता है, संचालन अभी भी परमाणु होना चाहिए। यह एक विशेष सीपीयू आधारित तुलना ऑपरेटर के माध्यम से किया जाता है (यही वजह है कि इन-मेमोरी केवल कुछ के साथ काम करती है [हालांकि पिछले 4 वर्षों में किए गए लगभग सभी सीपीयू] प्रोसेसर)। इस प्रकार हमें सब कुछ मुफ्त में नहीं मिलता है, फिर भी इन कार्यों को पूरा करने के लिए कुछ समय होगा।
इस तथ्य को सामने लाने का एक और तथ्य यह है कि लगभग सभी प्रश्नों में, उपयोग किया जाने वाला इंटरफ़ेस T-SQL (और मूल रूप से संकलित SPROCs) नहीं है, जो सभी कम से कम एक डिस्क आधारित तालिका को स्पर्श करते हैं। यही कारण है कि मेरा मानना है कि अंत में, हम वास्तव में किसी भी प्रदर्शन में वृद्धि नहीं कर रहे हैं क्योंकि हम अभी भी डिस्क आधारित तालिकाओं के प्रदर्शन के लिए विवश हैं।
जाँच करना:
Wait_completed के लिए एक विस्तारित ईवेंट सत्र बनाएं और आपको ज्ञात एक SPID निर्दिष्ट करें। क्वेरी चलाएँ और हमें आउटपुट दें या आंतरिक रूप से उपभोग करें।
# 1 से आउटपुट पर हमें अपडेट दें।
हैश इंडेक्स के लिए बाल्टी काउंट निर्धारित करने के लिए कोई जादुई संख्या नहीं है। मूल रूप से जब तक बाल्टी पूरी तरह से पूरी तरह से नहीं मिलती और पंक्ति श्रृंखला 3 या 4 से नीचे रहती है, तब तक प्रदर्शन स्वीकार्य रहना चाहिए। यह पूछने की तरह है, "मुझे अपनी लॉग फ़ाइल को किस पर सेट करना चाहिए?" - यह प्रति प्रक्रिया, प्रति डेटाबेस, प्रति उपयोग प्रकार पर निर्भर करने वाला है।
OPTION(OPTIMIZE FOR UNKNOWN)
( तालिका संकेत देखें ) प्रश्नों को चलाने की कोशिश की है ?