जटिल मानदंड के साथ अनुक्रमित प्रतिक्रियाओं को कम करना


12

मैं काम टिकटों के एक फायरबर्ड 2.5 डेटाबेस का अनुकूलन कर रहा हूं। वे एक तालिका में इस तरह के रूप में घोषित संग्रहीत हैं:

CREATE TABLE TICKETS (
  TICKET_ID id PRIMARY KEY,
  JOB_ID id,
  ACTION_ID id,
  STATUS str256 DEFAULT 'Pending'
);

मैं आमतौर पर पहला टिकट ढूंढना चाहता हूं जो संसाधित नहीं हुआ है और Pendingस्थिति में है।

मेरा प्रसंस्करण लूप होगा:

  1. जहां पहले टिकट प्राप्त किया Pending
  2. टिकट के साथ काम करो।
  3. अद्यतन टिकट स्थिति => Complete
  4. दोहराएँ।

कुछ भी नहीं फैंसी। अगर मैं डेटाबेस को देख रहा हूँ, जबकि यह लूप चलता है, तो मैं प्रत्येक पुनरावृत्ति के लिए अनुक्रमित रीड्स के चढ़ने की संख्या देखता हूं। प्रदर्शन बहुत बुरा नहीं लगता है कि मैं बता सकता हूं, लेकिन जिस मशीन पर मैं परीक्षण कर रहा हूं वह बहुत जल्दी है। हालाँकि, मुझे अपने कुछ उपयोगकर्ताओं से समय के साथ प्रदर्शन में गिरावट की रिपोर्ट मिली है।

मुझे एक इंडेक्स मिला है Status, लेकिन यह अभी भी ऐसा लगता है जैसे यह Ticket_Idप्रत्येक पुनरावृत्ति कॉलम को स्कैन करता है । ऐसा लगता है जैसे मैं कुछ देख रहा हूं, लेकिन मुझे यकीन नहीं है कि क्या। क्या अनुक्रमित की चढ़ाई संख्या कुछ इस तरह की उम्मीद है, या सूचकांक किसी तरह से दुर्व्यवहार कर रहा है?

- टिप्पणियों के लिए संपादन -

Firebird में आप पंक्ति पुनर्प्राप्ति को सीमित करते हैं:

Select First 1
  Job_ID, Ticket_Id
From
  Tickets
Where
  Status = 'Pending'

इसलिए जब मैं "पहले" कहता हूं, तो मैं इसे सीमित रिकॉर्ड सेट के लिए कह रहा हूं Status = 'Pending'


"रिट्रीव 1 टिकट जहां 'लंबित'" में "प्रथम" के साथ आपका क्या मतलब है ?
ypercube y

यदि "पहले" का अर्थ सबसे छोटा है ticket_id, तो आपको प्रोब्लेबी पर एक सूचकांक की आवश्यकता है(status, ticket_id)
ypercube

और आप कैसे सुनिश्चित हैं कि प्रदर्शन में गिरावट इस प्रक्रिया के कारण होती है न कि अन्य प्रश्नों / कथनों द्वारा।
अक्टूबर को ypercube y

@ypercube - नहीं, मैं निश्चित नहीं हूं कि प्रदर्शन में गिरावट कहां है। इसलिए मेरा सवाल था "क्या मुझे इससे चिंतित होने की आवश्यकता है, या क्या यह एक सूचकांक का सामान्य व्यवहार है?"। यह कुछ ऐसा है जिसे मैंने डेटाबेस की निगरानी करते हुए देखा, और मैंने इसे अप्रत्याशित माना। मैं यह उम्मीद नहीं करूंगा कि जब मैं एक अनुक्रमित स्तंभ के खिलाफ एक खंड प्रदान करता हूं तो पूर्ववर्ती पंक्तियों को स्कैन करना जारी रखूंगा। एफडब्ल्यूआईडब्ल्यू, इंडेक्स को संशोधित करने में शामिल करने के लिए ticket_idवास्तव में स्टेटस इंडेक्स होने की तुलना में खराब प्रदर्शन करता है।
gddc

क्या id(डेटा प्रकार) आपके द्वारा परिभाषित डोमेन है?
a_horse_with_no_name

जवाबों:


1

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

SQL सर्वर में (और शायद अन्य RDBMS की?), इसे फ़िल्टर किए गए अनुक्रमित का उपयोग करके काम किया जा सकता है। SQL सर्वर में आप अपने सूचकांक की परिभाषा के अंत में WHERE की शर्त यह कहने के लिए जोड़ेंगे कि "इस इंडेक्स को केवल स्टेटस <> 'कम्प्लीट' के साथ रिकॉर्ड में लागू करें"। फिर इस विधेय का उपयोग करने वाली कोई भी क्वेरी बहुत कम मात्रा में 'पूर्ण' पर सेट नहीं किए गए रिकॉर्ड्स की अनुक्रमणिका का उपयोग करेगी। हालाँकि, यहाँ दस्तावेज़ीकरण के आधार पर: http://www.firebirdsql.org/refdocs/langrefupd25-ddl-index.html , ऐसा नहीं लगता है कि फायरबर्ड फ़िल्टर्ड इंडेक्स का समर्थन करता है।

एक पुरालेख एक पुरालेख तालिका में 'पूर्ण' रिकॉर्ड डालने के लिए है। अपनी टिकट तालिका के रूप में ठीक उसी परिभाषा (हालांकि बिना किसी ऑटो जनरेट आईडी) के साथ एक तालिका बनाएं और पुरालेख रिकॉर्ड्स के 'पूर्ण' रिकॉर्ड को आगे बढ़ाकर उनके बीच की पंक्तियों को बनाए रखें। आपके टिकट टेबल पर सूचकांक फिर बहुत कम संख्या में रिकॉर्ड होगा और बहुत अधिक प्रदर्शन होगा। इसका अर्थ यह होगा कि आपको किसी भी रिपोर्ट आदि को बदलने की आवश्यकता होगी जो 'पूर्ण' टिकट को पुरालेख तालिका में इंगित करने के लिए या टिकट और संग्रह टिकट दोनों पर एक UNION करने के लिए संदर्भित करता है। इससे न केवल तेज़ होने का फायदा होगा, बल्कि इसका अर्थ यह भी होगा कि आप संग्रहणीय तालिका के लिए विशिष्ट अनुक्रमणिका बना सकते हैं ताकि यह अन्य प्रश्नों के लिए बेहतर प्रदर्शन कर सके (उदाहरण के लिए:

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


0

प्रदर्शन प्रभावित हुआ है या नहीं, यह डेटा की मात्रा और मशीन की क्षमता का कार्य होगा। आधुनिक हार्डवेयर की क्षमता को देखते हुए, टिकट बिक्री की मात्रा की कल्पना करना कठिन है, जिसे आपके द्वारा वर्णित डिज़ाइन द्वारा नियंत्रित नहीं किया जा सकता है। हालांकि, ऐसे बदलाव हैं जो मैं शुद्धता के लिए सुझाऊंगा, और एक माध्यमिक लाभ के रूप में प्रदर्शन में सुधार कर सकता है।

आपकी पहली लंबित क्वेरी गैर-नियतात्मक है। पहले किस आदेश के अनुसार? SQL तालिका में कोई आंतरिक आदेश नहीं है; First 1हैक केवल आपके दे रहा है कुछ मनमाने ढंग से पहले एक। यह निर्धारित करने के लिए, Job_ID क्रम में लंबित नौकरियों को संसाधित क्यों नहीं किया जाता है?

यदि आपके पास दो अनुक्रमणिका {Job_ID} और {Status, Job_ID} हैं, तो यह क्वेरी अनुमानित और कुशलता से एक पंक्ति लौटाएगी:

Select Job_ID, Ticket_Id
From   Tickets
Where Job_ID = ( 
  select min(Job_ID) from Tickets 
  where Status = 'Pending'
);

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

अन्य परिवर्तन जो मैं शुद्धता के लिए करूंगा, वह है Statusएक एकल, विवश बाइट बनाना और एप्लिकेशन को "लंबित" स्ट्रिंग की आपूर्ति करना। यह गलत Statusमानों से रक्षा करेगा , और संभवत: सूचकांक को सौदेबाजी में छोटा बनाता है। कुछ इस तरह:

CREATE TABLE TICKETS (
  TICKET_ID id PRIMARY KEY,
  JOB_ID id,
  ACTION_ID id,
  STATUS char(1) not NULL 
     DEFAULT 'P'
     CHECK( STATUS in ('P', 'C', 'X') ) -- whatever the domain is
);

बेशक, आप स्थिति के लिए विहित स्ट्रिंग्स की आपूर्ति करने के लिए एक दृश्य (या शायद एक व्युत्पन्न स्तंभ) का उपयोग कर सकते हैं।

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