2012-12-26 23 views
10

मैं InnoDB इंजन के साथ एक MySQL में एक मेज v_ext है अद्यतन के लिए सीमा 1:
- आईडी: प्राथमिक कुंजी
- कोड: पूर्व-निर्मित कोड की सूची (कहें 1000 कोड यादृच्छिक रूप से उत्पन्न होते हैं)
- user_id: प्रारंभ में NULLMySQL InnoDB का चयन करें ... बनाम अद्यतन ... सीमा 1

जब कोई उपयोगकर्ता कोई आइटम खरीदता है, तो उन्हें एक कोड प्राप्त होता है। मुझे user_id कॉलम को पॉप्युलेट करने के लिए तालिका को अपडेट करने की आवश्यकता है। अगर मैं उन एक ही समय में खरीद के हजारों है

START TRANSACTION; 
SELECT id FROM v_ext WHERE user_id IS NULL LIMIT 1 FOR UPDATE; -- return id 54 for ex. 
UPDATE v_ext SET user_id=xxx WHERE id=54; 
COMMIT; 

या

UPDATE v_ext SET user_id=xxx WHERE user_id IS NULL LIMIT 1; 

दूसरा विकल्प सुरक्षित है: मैं दो विकल्प हैं? यदि हां, तो क्या यह मानना ​​सही है कि यह दूसरा विकल्प प्रदर्शन के लिए बेहतर है क्योंकि इसे केवल एक प्रश्न की आवश्यकता है?

+0

क्या 'user_id' पर 'अद्वितीय' बाधा है? (यानी उपयोगकर्ता के पास केवल एक कोड हो सकता है)? – eggyal

+0

'EXISTS' समवर्तीता और प्रदर्शन के संदर्भ में बेहतर उपयोग होगा। – bonCodigo

+0

यूनिक एक बाधा नहीं है, उपयोगकर्ता_आईडी – JScoobyCed

उत्तर

10

चूंकि मुझे कोई जवाब नहीं मिला, इसलिए मैंने बेंचमार्किंग करना शुरू कर दिया। प्रदर्शन करने के लिए> EJB (जेपीए 2.0 EclipseLink, JTA) - ab -n 20000 -c 100

  • सर्वलेट:

    • 20.000 पहले से बनाई गई कोड
    • 20,000 अनुरोधों, 100 संगामिति साथ अपाचे ab आदेश का उपयोग: मेरे मापदंड इस प्रकार हैं डीबी में अपडेट करें (क्योंकि यह वास्तविक स्थिति में जेएसएफ एक्शन के माध्यम से होगा)
    • सर्वलेट के 2 संस्करण, विकल्प 1 के साथ एक (अद्यतन ... अद्यतन के लिए), और विकल्प 2 के साथ एक (अद्यतन ... LIMIT 1)
    • ग्लासफ़िश को रोक दिया गया, परीक्षण किए गए सर्वलेट को मैन्युअल रूप से गर्म करने के लिए 5 बार दबाएं अप, सभी रीसेट USER_ID को
    • टेस्ट 3 बार प्रत्येक चलाए जा रहे हैं और औसत

    परिणाम प्रदान की जाती है शून्य पर:

    का चयन करें ... अद्यतन के लिए; अद्यतन ...:

    Concurrency Level:  100 
    Time taken for tests: 758.116 seconds 
    Complete requests:  20000 
    Failed requests:  0 
    Write errors:   0 
    Row updated:   20000 
    

    अद्यतन .... सीमा 1:

    Concurrency Level:  100 
    Time taken for tests: 773.659 seconds 
    Complete requests:  20000 
    Failed requests:  0 
    Write errors:   0 
    Row updated:   20000 
    

    तो कम से कम अपने सिस्टम पर, 2 प्रश्नों के साथ विकल्प एक क्वेरी से अधिक कुशल लगता है। मुझे उम्मीद नहीं थी :)

  • +0

    +1 दिलचस्प निष्कर्ष पोस्ट कर रहा हूं। क्या यह किसी भी सहमति के मुद्दों का कारण बनता है? –

    +0

    ऐसा नहीं है कि मैं देख सकता हूं। मैंने 20,000 सफल अनुरोधों के माध्यम से 20,000 पंक्तियां अपडेट कीं। – JScoobyCed

    +0

    डेडलॉक के साथ प्रश्न का पालन करें जब मैं उपयोगकर्ता_आईडी वास्तव में एक वर्चर कॉलम इंडेक्स करता हूं) http://stackoverflow.com/questions/14052038/mysql-select-for-update-with-index-has-concurrency-issue – JScoobyCed