इन-मेमोरी टेबल का प्रदर्शन डिस्क-आधारित टेबल से भी बदतर है


10

मेरे पास SQL ​​सर्वर 2014 में एक तालिका है जो निम्न की तरह दिखता है:

CREATE TABLE dbo.MyTable
(
[id1] [bigint] NOT NULL,
[id2] [bigint] NOT NULL,
[col1] [int] NOT NULL default(0),
[col2] [int] NOT NULL default(0)
)

(id1, id2) पीके होने के साथ। मूल रूप से, id1 परिणामों के एक समूह (id2, col1, col2) के समूह के लिए एक पहचानकर्ता है, जिसका pk id2 है।

मैं एक मौजूदा डिस्क-आधारित तालिका से छुटकारा पाने के लिए इन-मेमोरी टेबल का उपयोग करने की कोशिश कर रहा हूं जो मेरी अड़चन है।

  • तालिका में डेटा लिखा है -> पढ़ा -> एक बार हटा दिया गया।
  • प्रत्येक id1 मान में कई (दसियों / सैकड़ों) id2 के हजारों होते हैं।
  • डेटा को बहुत कम समय के लिए तालिका में संग्रहीत किया जाता है, जैसे 20 सेकंड।

इस तालिका पर किए गए प्रश्न निम्नलिखित हैं:

-- INSERT (can vary from 10s to 10,000s of records):
INSERT INTO MyTable
  SELECT @fixedValue, id2, col1, col2 FROM AnotherTable

-- READ:
SELECT id2, col1
FROM MyTable INNER JOIN OtherTbl ON MyTable.id2 = OtherTbl.pk
WHERE id1 = @value
ORDER BY col1

-- DELETE:
DELETE FROM MyTable WHERE id1 = @value

यहां वर्तमान परिभाषा है जो मैंने तालिका के लिए उपयोग की है:

CREATE TABLE dbo.SearchItems
(
  [id1] [bigint] NOT NULL,
  [id2] [bigint] NOT NULL,
  [col1] [int] NOT NULL default(0),
  [col2] [int] NOT NULL default(0)

  CONSTRAINT PK_Mem PRIMARY KEY NONCLUSTERED (id1,id2),
  INDEX idx_Mem HASH (id1,id2) WITH (BUCKET_COUNT = 131072)
) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_ONLY)

दुर्भाग्य से, इस परिभाषा के परिणामस्वरूप डिस्क-आधारित तालिका के साथ पिछली स्थिति के संबंध में प्रदर्शन में गिरावट आई है। परिमाण का क्रम कम से कम 10% अधिक है (कि कुछ मामलों में 100% तक पहुंच जाता है, इसलिए दोहरा समय)।

सबसे अधिक, मैं Microsoft द्वारा विज्ञापित लॉक-फ्री आर्किटेक्चर को देखते हुए उच्च-संगामिति परिदृश्यों में सुपर-लाभ प्राप्त करने की उम्मीद कर रहा था। इसके बजाय, सबसे खराब प्रदर्शन तब होता है जब कई समवर्ती उपयोगकर्ता टेबल पर कई प्रश्न चला रहे होते हैं।

प्रशन:

  • सही BUCKET_COUNT सेट करने के लिए क्या है?
  • मुझे किस तरह के सूचकांक का उपयोग करना चाहिए?
  • डिस्क-आधारित तालिका के साथ प्रदर्शन खराब क्यों हैं?

Sysinos_db_xtp_hash_index_stats रिटर्न की एक क्वेरी :

total_bucket_count = 131,072
empty_bucket_count = 0
avg_chain_len = 873
max_chain_length = 1009

मैंने बाल्टी गणना को बदल दिया है इसलिए sysinos_db_xtp_hash_index_stats से आउटपुट है:

total_bucket_count = 134217728
empty_bucket_count = 131664087
avg_chain_len = 1
max_chain_length = 3

फिर भी, परिणाम लगभग समान हैं, यदि बदतर नहीं हैं।


क्या आप सुनिश्चित हैं कि आप पैरामीटर सूँघने में नहीं चल रहे हैं? क्या आपने OPTION(OPTIMIZE FOR UNKNOWN)( तालिका संकेत देखें ) प्रश्नों को चलाने की कोशिश की है ?
टीटी।

मेरा अनुमान है कि आप पंक्ति श्रृंखला के मुद्दों में भाग रहे हैं। क्या आप हमें इसका आउटपुट दे सकते हैं select * from sys.dm_db_xtp_hash_index_stats ? इसके अलावा, इस लिंक को आपके सभी प्रश्नों का उत्तर देना चाहिए: msdn.microsoft.com/en-us/library/…
सीन गैलार्डी

4
हैश इंडेक्स केवल शामिल दोनों कॉलम पर विधेय के लिए उपयोगी है। क्या आपने मेज पर हैश इंडेक्स के बिना कोशिश की है?
मिकेल एरिकसन

मैंने पाया है कि इन-मेमोरी तकनीक के साथ सबसे अच्छा प्रदर्शन सुधार केवल देशी संकलित संग्रहीत प्रक्रियाओं का उपयोग करके प्राप्त किया जा सकता है ।
डैनियल Hutmacher

@DanielHutmacher FWIW मैंने उन काउंटर-उदाहरणों को देखा है जहां सभी लाभ को हटाने से और देशी संकलित प्रक्रियाओं को जोड़ने से शून्य या नगण्य सुधार दिया गया था। मुझे नहीं लगता कि कंबल बयान के लिए कोई जगह है (हालांकि आप इस मामले में सही हो सकते हैं, मैंने विवरणों पर ध्यान नहीं दिया है)।
हारून बर्ट्रेंड

जवाबों:


7

हालांकि यह पोस्ट जानकारी की कमी के कारण पूर्ण उत्तर नहीं होगी, यह आपको उचित दिशा में इंगित करने में सक्षम होना चाहिए या अन्यथा अंतर्दृष्टि प्राप्त करना चाहिए जिसे आप बाद में समुदाय के साथ साझा कर सकते हैं।

दुर्भाग्य से, इस परिभाषा के परिणामस्वरूप डिस्क-आधारित तालिका के साथ पिछली स्थिति के संबंध में प्रदर्शन में गिरावट आई है। परिमाण का क्रम कम से कम 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) नहीं है, जो सभी कम से कम एक डिस्क आधारित तालिका को स्पर्श करते हैं। यही कारण है कि मेरा मानना ​​है कि अंत में, हम वास्तव में किसी भी प्रदर्शन में वृद्धि नहीं कर रहे हैं क्योंकि हम अभी भी डिस्क आधारित तालिकाओं के प्रदर्शन के लिए विवश हैं।

जाँच करना:

  1. Wait_completed के लिए एक विस्तारित ईवेंट सत्र बनाएं और आपको ज्ञात एक SPID निर्दिष्ट करें। क्वेरी चलाएँ और हमें आउटपुट दें या आंतरिक रूप से उपभोग करें।

  2. # 1 से आउटपुट पर हमें अपडेट दें।

  3. हैश इंडेक्स के लिए बाल्टी काउंट निर्धारित करने के लिए कोई जादुई संख्या नहीं है। मूल रूप से जब तक बाल्टी पूरी तरह से पूरी तरह से नहीं मिलती और पंक्ति श्रृंखला 3 या 4 से नीचे रहती है, तब तक प्रदर्शन स्वीकार्य रहना चाहिए। यह पूछने की तरह है, "मुझे अपनी लॉग फ़ाइल को किस पर सेट करना चाहिए?" - यह प्रति प्रक्रिया, प्रति डेटाबेस, प्रति उपयोग प्रकार पर निर्भर करने वाला है।

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