के रूप में डेटाबेस तालिका का उपयोग करना मैं एक कतार के रूप में डेटाबेस तालिका का उपयोग करना चाहता हूं। मैं इसमें सम्मिलित करना चाहता हूं और इसमें से सम्मिलित क्रम (एफआईएफओ) में तत्व लेना चाहता हूं। मेरा मुख्य विचार प्रदर्शन है क्योंकि मेरे पास प्रत्येक सेकेंड में इनमें से हजार लेनदेन हैं। तो मैं एक एसक्यूएल क्वेरी का उपयोग करना चाहता हूं जो मुझे पूरी तालिका को खोजे बिना पहला तत्व देता है। जब मैं इसे पढ़ता हूं तो मैं एक पंक्ति को नहीं हटाता हूं। शीर्ष 1 चुनें ..... यहां सहायता करें? क्या मुझे किसी विशेष इंडेक्स का उपयोग करना चाहिए?एक कतार
एक कतार
उत्तर
मैं प्रत्येक पंक्तिबद्ध आइटम के लिए विशिष्ट रूप से वृद्धि आईडी प्रदान करने के लिए प्राथमिक कुंजी के रूप में एक पहचान क्षेत्र का उपयोग करता हूं, और उस पर एक क्लस्टर इंडेक्स चिपकाता हूं। यह उस क्रम का प्रतिनिधित्व करेगा जिसमें वस्तुओं को कतारबद्ध किया गया था।
जब आप उन्हें संसाधित करते हैं तो आइटम को कतार तालिका में रखने के लिए, आपको किसी विशेष आइटम की वर्तमान स्थिति इंगित करने के लिए "स्थिति" फ़ील्ड की आवश्यकता होगी (उदाहरण के लिए 0 = प्रतीक्षा, 1 = संसाधित किया जा रहा है, 2 = संसाधित) । किसी आइटम को दो बार संसाधित करने से रोकने के लिए इसकी आवश्यकता होती है।
कतार में वस्तुओं को संसाधित करते समय, आपको तालिका में अगला आइटम ढूंढना होगा, वर्तमान में संसाधित नहीं किया जा रहा है। इसे इस तरह से होने की आवश्यकता होगी ताकि एक ही आइटम को एक ही समय में प्रदर्शित करने के लिए कई प्रक्रियाओं को रोकने के लिए नीचे दिखाया जा सके। table hints UPDLOCK और READPAST पर ध्यान दें जिन्हें आपको कतार लागू करने के बारे में पता होना चाहिए।
उदा। एक स्पोक के भीतर, इस तरह कुछ:
DECLARE @NextID INTEGER
BEGIN TRANSACTION
-- Find the next queued item that is waiting to be processed
SELECT TOP 1 @NextID = ID
FROM MyQueueTable WITH (UPDLOCK, READPAST)
WHERE StateField = 0
ORDER BY ID ASC
-- if we've found one, mark it as being processed
IF @NextId IS NOT NULL
UPDATE MyQueueTable SET Status = 1 WHERE ID = @NextId
COMMIT TRANSACTION
-- If we've got an item from the queue, return to whatever is going to process it
IF @NextId IS NOT NULL
SELECT * FROM MyQueueTable WHERE ID = @NextID
यदि कोई आइटम संसाधित करने में विफल रहता है, तो क्या आप इसे बाद में पुनः प्रयास करने में सक्षम होना चाहते हैं? यदि ऐसा है, तो आपको या तो स्थिति को 0 या कुछ पर रीसेट करने की आवश्यकता होगी। इसके लिए और विचार की आवश्यकता होगी।
वैकल्पिक रूप से, डेटाबेस तालिका को कतार के रूप में उपयोग न करें, लेकिन एमएसएमक्यू की तरह कुछ - बस सोचा कि मैं इसे मिश्रण में फेंक दूंगा!
मुझे चुनिंदा आईडी से चयन आईडी को अलग क्यों करना चाहिए? – Shayan
आपको ऐसा करने की ज़रूरत नहीं है, आप पहले वैल्यू के रूप में एक ही समय में वैरिएबल में आवश्यक सभी मान लोड कर सकते हैं, और फिर अंत में उन्हें वापस कर सकते हैं। इसके अलावा, मैंने सादगी के लिए "चयन *" किया है - केवल उन फ़ील्ड को वापस लौटें जिन्हें आपको वास्तव में चाहिए। – AdaTheDev
मैं प्रोग्राम के विभिन्न हिस्सों के लॉकिंग प्रभाव को कम करने के लिए इस तालिका में विदेशी कुंजी के साथ प्रक्रिया तालिका को एक अलग तालिका में रखना चाहता हूं। क्या यह विधि मदद करता है? इसके लिए मुझे किस प्रकार की अनुक्रमणिका का उपयोग करना चाहिए? – Shayan
सब कुछ आपके डेटाबेस इंजन/कार्यान्वयन पर निर्भर करता है।
मेरे लिए निम्नलिखित कॉलम के साथ टेबल पर सरल कतार:
id/task/priority/date_added
आमतौर पर काम करता है।
मैंने समूह कार्यों को प्राथमिकता और कार्य का उपयोग किया और दोगुनी कार्य के मामले में मैंने इसे बड़ी प्राथमिकता के साथ चुना।
और चिंता न करें - आधुनिक डेटाबेस के लिए "हजारों" कुछ खास नहीं है।
के लिए एसक्यूएल का उपयोग करें ये क्या हैं? मैं SQL सर्वर 2008 का उपयोग करता हूं। – Shayan
मुझे लगता है कि आप "टेबल" ऊपर दिए गए स्थानों में से एक में "इंडेक्स" का मतलब है (मैं इसे ठीक कर दूंगा, लेकिन मैं * 100% * निश्चित नहीं हूं कि कौन सा टाइपो है)। –
क्षमा करें, मेरे मामले में सभी कॉलम पर "कॉलम" – bluszcz
यदि आप अपनी संसाधित पंक्तियों को नहीं हटाते हैं, तो आपको किसी प्रकार के ध्वज की आवश्यकता होगी जो इंगित करता है कि एक पंक्ति पहले ही संसाधित हो चुकी है।
उस ध्वज पर एक सूचकांक डालें, और उस कॉलम पर जिसे आप ऑर्डर करने जा रहे हैं।
उस झंडे पर अपनी तालिका को विभाजित करें, इसलिए अस्वीकृत लेनदेन आपके प्रश्नों को छेड़छाड़ नहीं कर रहे हैं।
यदि आपको वास्तव में 1.000
संदेश हर सेकेंड मिलेंगे, तो परिणामस्वरूप 86.400.000
पंक्तियां एक दिन होगी। आप पुरानी पंक्तियों को साफ करने के किसी तरीके के बारे में सोचना चाह सकते हैं।
ध्वज क्या है? – Shayan
'ध्वज'' से मेरा मतलब है कि कुछ कॉलम याद रखें, अगर आपके क्लाइंट द्वारा एक पंक्ति पहले ही संसाधित हो चुकी है। –
मेरा मानना है कि उनका मतलब था कि आप अपनी टेबल पर एक कॉलम जोड़ सकते हैं - शायद अस्वीकृत - जो प्रत्येक लेनदेन की स्थिति रखेगा।चूंकि आप उन्हें हटाने के बाद पंक्तियों को हटा नहीं रहे हैं, इसलिए आपको यह जानने का एक तरीका होना चाहिए कि कौन से लेन-देन को अनदेखा करना है। आप इसे थोड़ा सा क्षेत्र बना सकते हैं, 0 कतार के लिए 0 और डेक्यूड के लिए 1। –
शायद अपने चुनिंदा बयान में मदद मिलेगी की एक सीमा होती = 1 जोड़ रहा है ... एक भी मैच के बाद वापसी ...
टॉप 1 के साथ क्या अंतर है? – Shayan
मुझे पता है कि SQL सर्वर शीर्ष 1 का उपयोग कर सकता है पोस्टग्रेज़ में LIMIT 1 जैसा ही है। मुझे कल्पना है कि अन्य सभी विक्रेता एक या दूसरे को स्वीकार करेंगे। – Matt
मैं ईमानदार रहूंगा, मुझे एहसास नहीं हुआ कि वे एक ही चीज़ के बराबर थे ... मैंने कभी भी शीर्ष वाक्यविन्यास का उपयोग नहीं किया है, केवल LIMIT ... यही कारण है कि मैं स्टैक ओवरफ्लो से प्यार करता हूं: यहां तक कि एक उत्तर देने में भी, मैं कुछ नया सीखता हूँ। –
एक तारीख (या autoincrement) स्तंभ पर एक क्लस्टर सूचकांक बनाएं मजबूर। यह सूचकांक क्रम में मोटे तौर पर तालिका में पंक्तियों को रखेगा और जब आप ORDER BY
अनुक्रमित कॉलम पर तेजी से इंडेक्स-आधारित पहुंच की अनुमति देंगे। TOP X
(या LIMIT X
का उपयोग करके, अपने आरडीएमबीएस के आधार पर) केवल सूचकांक से पहले एक्स आइटम पुनर्प्राप्त करेगा।
प्रदर्शन चेतावनी: ऑप्टिमाइज़र अप्रत्याशित चीजें नहीं करता है, यह सत्यापित करने के लिए आपको हमेशा अपने प्रश्नों (वास्तविक डेटा पर) की निष्पादन योजनाओं की समीक्षा करनी चाहिए। सूचित निर्णय लेने में सक्षम होने के लिए अपने प्रश्नों (फिर से वास्तविक डेटा पर) बेंचमार्क करने का प्रयास करें।
जब तक आप डालने के समय के ट्रैक को ट्रैक रखने के लिए कुछ उपयोग करते हैं, तब तक यह कोई परेशानी नहीं होगी। mysql options के लिए यहां देखें। सवाल यह है कि क्या आपको केवल सबसे हाल ही में सबमिट की गई वस्तु की आवश्यकता है या फिर आपको फिर से शुरू करने की आवश्यकता है या नहीं। यदि आपको पुन: प्रयास करने की आवश्यकता है, तो आपको ORDER BY
कथन, लूप के माध्यम से, और को अंतिम डेटाटाइम याद रखने के लिए क्या करना है ताकि आप अपना अगला हिस्सा पकड़ सकें।
चूंकि आप तालिका से रिकॉर्ड नहीं हटाते हैं, इसलिए आपको (processed, id)
पर एक समग्र अनुक्रमणिका होना चाहिए, जहां processed
वह कॉलम है जो इंगित करता है कि वर्तमान रिकॉर्ड संसाधित किया गया था या नहीं।
सबसे अच्छी बात आपके रिकॉर्ड के लिए विभाजित तालिका तैयार करेगी और PROCESSED
विभाजन कुंजी को फ़ील्ड करेगी। इस तरह, आप तीन या अधिक स्थानीय इंडेक्स रख सकते हैं।
हालांकि, अगर आप हमेशा id
क्रम में रिकॉर्ड केवल दो राज्यों की प्रक्रिया है, और है, रिकॉर्ड को अपडेट करने का मतलब होगा सिर्फ सूचकांक की पहली पत्ती से रिकॉर्ड लेने और पिछले पत्ती
करने के लिए इसे जोड़कर वर्तमान में संसाधित रिकॉर्ड में सभी अप्रत्याशित रिकॉर्ड्स के कम से कम id
और सभी संसाधित रिकॉर्ड्स के सबसे बड़े id
होंगे।
मैं प्रोग्राम के विभिन्न हिस्सों के लॉकिंग प्रभाव को कम करने के लिए इस तालिका में विदेशी कुंजी के साथ प्रक्रिया तालिका को एक अलग तालिका में रखना चाहता हूं। – Shayan
'@ शायन': इससे आपके चयन प्रदर्शन पर गंभीर प्रभाव पड़ेगा। और वैसे भी प्रसंस्करण करते समय आपको फ़ील्ड को लॉक करने की आवश्यकता है। – Quassnoi
लेनदेन नहीं होने के लिए इसके लिए एक बहुत ही आसान समाधान, ताले आदि परिवर्तन ट्रैकिंग तंत्र (डेटा कैप्चर नहीं) का उपयोग करना है। यह प्रत्येक जोड़ा/अपडेट/हटाई गई पंक्ति के लिए वर्जनिंग का उपयोग करता है ताकि आप ट्रैक कर सकें कि किसी विशिष्ट संस्करण के बाद क्या परिवर्तन हुआ।
तो, आप अंतिम संस्करण जारी रखते हैं और नए परिवर्तनों की क्वेरी करते हैं।
यदि कोई क्वेरी विफल हो जाती है, तो आप हमेशा वापस जा सकते हैं और अंतिम संस्करण से डेटा पूछ सकते हैं। इसके अलावा, यदि आप एक प्रश्न के साथ सभी परिवर्तन नहीं करना चाहते हैं, तो आप अंतिम संस्करण द्वारा शीर्ष एन ऑर्डर प्राप्त कर सकते हैं और सबसे बड़ा संस्करण स्टोर कर सकते हैं जो आपको फिर से पूछने के लिए मिला है।
परिवर्तन ट्रैकिंग कैसे आपको डेटाबेस तालिका का उपयोग कतार के रूप में करने में मदद करती है? एक कतार में, आप अगला उपलब्ध कार्य (एफआईएफओ ऑर्डर में) प्राप्त करना चाहते हैं, जिसे पहले ही संसाधित नहीं किया गया है, और यह सुनिश्चित करें कि आइटम केवल एक बार संसाधित हो जाए। परिवर्तन ट्रैकिंग पूरी तरह से अलग समस्या हल करती है - आखिरी पूछताछ के बाद से तालिका की कौन सी पंक्तियां बदल गई हैं। मैं कनेक्शन नहीं देख रहा हूँ। –
अच्छा बिंदु ब्रायन और आप सही हैं। मैंने परिवर्तन ट्रैकिंग का प्रस्ताव दिया ताकि टेबल कतारों की आवश्यकता नहीं होगी। वह मेरा मुद्दा था। कतार भरने के लिए ट्रिगर्स (संभवतः) या कुछ और का उपयोग करने के बजाय, कोई भी स्रोत तालिकाओं से परिवर्तन प्राप्त करने के लिए परिवर्तन ट्रैकिंग तंत्र का उपयोग कर सकता है, जब तक कि वह परिवर्तनों को ट्रैक करना चाहता है ..... टिप्पणी के लिए धन्यवाद। –
- 1. एक कतार
- 2. एक कतार
- 3. एक कतार
- 4. एक ही कतार
- 5. एक एमएसएमक्यू आउटगोइंग कतार
- 6. कतार
- 7. कतार
- 8. माइक्रोसॉफ्ट संदेश कतार - प्राथमिकता झंडा या एक अलग कतार?
- 9. साधारण कतार बनाम SEDA कतार
- 10. एक Azure सेवा बस कतार
- 11. एक कतार के बिना ThreadPoolExecutor
- 12. स्थान प्रबंधक एक प्रेषण कतार
- 13. एक निजी रिमोट MSMQ कतार
- 14. क्यों एक विंडोज़ संदेश कतार
- 15. जावा में एक तेज कतार
- 16. रेस्क्यू: एक कार्यकर्ता प्रति कतार
- 17. संदेश कतार बनाम कार्य कतार अंतर
- 18. MSMQ - एक कतार एक कतार प्रक्रिया पुनः आरंभ/सर्वर पुनः आरंभ
- 19. अपलोड कतार
- 20. एसिंक्रोनस कतार
- 21. ऑडियो कतार
- 22. थ्रेड कतार
- 23. प्राथमिकता कतार
- 24. स्थिर कतार
- 25. अपनी कतार
- 26. एसटीएल कतार
- 27. प्राथमिकता कतार
- 28. प्रकाशन कतार
- 29. जेएमएस कतार
- 30. कतार AJAX
के लिए इस देखें कैसे एसक्यूएल सर्वर में एक कतार लागू करने के लिए का अच्छा वर्णन के लिए यह लेख देखें: http://www.mssqltips.com/sqlservertip/1257/processing-data-queues-in -एसक्ल-सर्वर-साथ-रीडपैस्ट-एंड-अपडेटलॉक/ –
पंक्ति-आधारित तर्क का उपयोग करते हुए जैसे SQL सर्वर में कतार को प्रोसेस करना संसाधनों का एक बड़ा दुरुपयोग है .. सेट-आधारित तर्क –