2011-11-30 13 views
5

मेरे पास PostgreSQL 9.0 पर DELETE/INSERT अनुक्रमों के साथ एक थ्रूपुट समस्या है। मैं स्थिति सुधारने के लिए विचारों की तलाश में हूं।PostgreSQL DELETE/INSERT थ्रूपुट समस्या

हमारे लिए उपलब्ध हार्डवेयर पर, मैं प्रत्येक पंक्ति में 1 एम पंक्तियों से परे 3000/एस (समान रूप से 10 टेबलों में) की निरंतर दर पर डेटाबेस में नई पंक्तियां डाल सकता हूं, जिसे मैं आमतौर पर परीक्षण करता हूं। हालांकि, अगर मैं एक मोड पर स्विच करता हूं जहां हम एक पंक्ति को हटाते हैं और इसे विभिन्न डेटा के साथ फिर से दर्ज करते हैं, तो प्रदर्शन 250 पंक्तियों/एस (फिर से, समान रूप से 10 तालिकाओं में) के आयाम के क्रम से अधिक हो जाता है।

किसी भी तालिका पर कोई बाधा नहीं है। 1 जीबी के कुल इंडेक्स आकार (प्रति टेबल 1 एम पंक्तियों) के साथ प्रत्येक तालिका में 2 अनुक्रमित कॉलम हैं जो साझा_बफर (2 जीबी) के भीतर आराम से हैं। कुल डेटा आकार (प्रति टेबल 1 एम पंक्तियों पर) 12 जीबी है, जो कुल सिस्टम रैम से काफी कम है। यह एक छाया डेटाबेस है जहां हम आपातकाल में पुनर्निर्माण कर सकते हैं, इसलिए हम fsync के साथ भागते हैं।

ऐसा प्रतीत होता है कि जब हम पॉप्युलेट मोड में होते हैं, तो हमें बहुत कम डिस्क खोज समय से लाभ होता है क्योंकि डेटा जोड़ा जा रहा है। हालांकि, जब हम अपडेट मोड पर स्विच करते हैं, तो वहां बहुत सारी मांगें होती हैं (संभवतः पुराने पंक्तियों को हटाने के लिए)। यादृच्छिक डिस्क लागत ~ 8ms (= ~ 125 प्रति सेकेंड) की तलाश है। क्या कोई तरीका है (हार्डवेयर में बदलाव के बिना) कि हम अद्यतन/पुनः-आईएनएसईआरटी संचालन के प्रदर्शन में काफी सुधार कर सकते हैं?

EDIT1: मैं दो अलग-अलग spec हार्डवेयर प्लेटफॉर्म पर perf परीक्षण कर रहा हूं। जिन नंबरों को मैंने पहले उद्धृत किया था वे उच्च स्पेक प्लेटफ़ॉर्म से थे। मैंने अभी निचले स्पेक प्लेटफॉर्म पर टेस्ट रन पूरा कर लिया है। इस परीक्षण में मैं जितनी जल्दी हो सके नई पंक्तियों को सम्मिलित करता हूं, प्रत्येक 10 सेकंड में सम्मिलित दर लॉगिंग करता हूं, जब तक कि मैंने 1 मिलियन पंक्तियां डाली न हों। इस बिंदु पर मेरी टेस्ट स्क्रिप्ट यादृच्छिक पंक्तियों को अद्यतन करने के लिए स्विच करती है।

Perf results graph

यह ग्राफ से पता चलता मापा अद्यतन दर ~ था सभी 10 टेबल/दूसरी आबादी के दौरान और अद्यतन दर दूसरे सभी 10 टेबल/करने के लिए < 10 अपडेट किया गया 150 अद्यतन।

@ विल्डप्लेसर - मशीन एक असली मशीन है, वीएम नहीं। 10 टेबल में सभी स्कीमा हैं।

CREATE TABLE objecti_servicea_item1 
(
    iss_scs_id text, 
    iss_generation bigint, 
    boolattr1 boolean, 
    boolattr2 boolean, 
    boolattr3 boolean, 
    boolattr4 boolean, 
    boolattr5 boolean, 
    boolattr6 boolean, 
    boolattr7 boolean, 
    boolattr8 boolean, 
    boolattr9 boolean, 
    boolattr10 boolean, 
    boolattr11 boolean, 
    boolattr12 boolean, 
    boolattr13 boolean, 
    boolattr14 boolean, 
    boolattr15 boolean, 
    boolattr16 boolean, 
    boolattr17 boolean, 
    intattr1 bigint, 
    intattr2 bigint, 
    intattr3 bigint, 
    intattr4 bigint, 
    intattr5 bigint, 
    intattr6 bigint, 
    intattr7 bigint, 
    intattr8 bigint, 
    intattr9 bigint, 
    intattr10 bigint, 
    intattr11 bigint, 
    intattr12 bigint, 
    intattr13 bigint, 
    intattr14 bigint, 
    intattr15 bigint, 
    intattr16 bigint, 
    intattr17 bigint, 
    strattr1 text[], 
    strattr2 text[], 
    strattr3 text[], 
    strattr4 text[], 
    strattr5 text[], 
    strattr6 text[], 
    strattr7 text[], 
    strattr8 text[], 
    strattr9 text[], 
    strattr10 text[], 
    strattr11 text[], 
    strattr12 text[], 
    strattr13 text[], 
    strattr14 text[], 
    strattr15 text[], 
    strattr16 text[], 
    strattr17 text[] 
) 
WITH (
    OIDS=FALSE 
); 
CREATE INDEX objecti_servicea_item1_idx_iss_generation 
    ON objecti_servicea_item1 
    USING btree 
    (iss_generation); 
CREATE INDEX objecti_servicea_item1_idx_iss_scs_id 
    ON objecti_servicea_item1 
    USING btree 
    (iss_scs_id); 

"अद्यतन" किए जा रहे "10" प्रत्येक तालिका के लिए निम्नलिखित SQL शामिल हैं।

DELETE FROM ObjectI_ServiceA_Item1 WHERE iss_scs_id = 'ObjUID39' 
INSERT INTO ObjectI_ServiceA_Item1 
VALUES ('ObjUID39', '2', '0', NULL, '0' 
, NULL, NULL, NULL, '1', '1', NULL, '0' 
, NULL, NULL, NULL, NULL, '0', '1', '1' 
, '-70131725335162304', NULL, NULL, '-5241412302283462832' 
, NULL, '310555201689715409', '575266664603129486' 
, NULL, NULL, NULL, NULL, NULL, NULL 
, '-8898556182251816700', NULL, '3325820251460628173' 
, '-3434461681822953613' 
, NULL 
, E'{pvmo2mt7dma37roqpuqjeu4p8b,"uo1kjt1b3eu9g5vlf0d02l6iaq\\\\\\",",45kfns1j80gc7fri0dm29hnrjo}' 
, NULL, NULL 
, E'{omjv460do8cb7abn8t3eg5b6ki,"a7hrlninbk1rmu6h3rd4787l7f\\\\\\",",24n3ipfua5spma2vrj2aji98g3}' 
, NULL 
, E'{1821v2n2ermm4jujrucu5tekmm,"ukgst224964uhthkhjj9v189ft\\\\\\",",6dfsaniq9mftvbdr8g1sr8e6as}' 
, E'{c2a9gvf0fnd38m8vprlhkp2n74,"ts86vbat12lfr0d7l4tc29k9uk\\\\\\",",32b5j9r5evmrie4h21hi10dpot}' 
, E'{18pve4cmcbrjiom9bpvoo1l4n0,"hrqcsane6r0n7u2oj79bj605rh\\\\\\",",32q5n18q3qbkuit605fv47270o}' 
, E'{l3bf96shrpnnqgt35m7574t5n4,"cpol4k8296hbdqc9kac79oj0ua\\\\\\",",eqioulmb7vav10lbnc5jg752df}' 
, E'{5fai108h163hpjcv0ofgfi7c28,"ci958009ddak3li7bp37slcs8i\\\\\\",",2itstj01tkprlul8f530uhs6s2}' 
, E'{ueqfkdold8vc84jllr4b2cakt5,"t5vbea4r7tva091pa8j6886t60\\\\\\",",ul82aovhil1lpd290s14vd0p3i}' 
, NULL, NULL, NULL, NULL, NULL) 

ध्यान दें कि के दौरान मेरी पर्फ़ के पहले चरण का परीक्षण हटाएँ आदेश हमेशा कुछ भी नहीं होगा।

@ फ्रैंक हेइकेंस - पेर्फ परीक्षण में जो मैं अद्यतन कर रहा हूं 10 धागे से किया जा रहा है। हालांकि, अद्यतनों को धागे को इस तरह से असाइन किया जाता है जो सुनिश्चित करता है कि एक ही पंक्ति के एकाधिक अपडेट हमेशा एक ही धागे से संभाले जाते हैं।

+0

क्या यह एक वीएम या असली मशीन है? कृपया तालिका परिभाषा और क्वेरी के एक खंड (जोड़ें) और प्रश्न के परिणामस्वरूप क्वेरी योजना जोड़ें। – wildplasser

+0

क्या आपने ताले की जांच की? एकाधिक प्रक्रियाएं एक ही रिकॉर्ड को हटाने का प्रयास कर सकती हैं। –

+0

मैंने आपकी टिप्पणी का जवाब देने के लिए अपनी पोस्ट संपादित की है। – mchr

उत्तर

3

यह डाटामॉडल एक सौंदर्य नहीं है, हटाएं - INSERT या तो। अद्यतन के साथ क्या गलत है? यदि UP_ATE में iss_generation और iss_scs_id अद्यतन नहीं होता है, तो डेटाबेस प्रदर्शन को बढ़ाने के लिए HOT update (हीप ओवरफ़्लो टुपल) कर सकता है। अद्यतन को कम fillfactor से भी लाभ होगा।

जब आप किसी रिकॉर्ड का डिलीट करते हैं, तो यह रिकॉर्ड अलग-अलग ब्लॉक में हो सकता है जहां INSERT जाएगा। निचले fillfactor का उपयोग करके और UPDATE का उपयोग कर, डेटाबेस को डिस्क पर उसी ब्लॉक में अद्यतन रिकॉर्ड को हटाने और INSERT करने का विकल्प दे सकता है। इसके परिणामस्वरूप कम यादृच्छिक I/O होगा।जब हॉट का उपयोग किया जा सकता है, चीजें बेहतर होती हैं क्योंकि इंडेक्स को अपडेट करने की कोई आवश्यकता नहीं होती है।

1

सुनिश्चित नहीं है, लेकिन शायद fillfactor को बदलने में मदद मिलेगी?

+0

सुझाव के लिए धन्यवाद - मैं इसे देख लूंगा। – mchr

0

हमें स्मृति में सीएसवी से हटा/प्रतिलिपि के साथ सफलता मिली है।