2012-04-07 21 views
59

मैंने हाल ही में पोस्टग्रेस से सोलर तक स्विच किया और हमारे प्रश्नों में ~ 50x की गति देखी। हमारे द्वारा चलाए जाने वाले प्रश्नों में कई श्रेणियां शामिल हैं, और हमारा डेटा वाहन सूची है। उदाहरण के लिए: "$ 5000 < कीमत < $ 10,000 लाभ < 50,000 के साथ सभी वाहनों का पता लगाएं,, = माज़दा बनाने ..."पोस्टग्रेज़ से सौर इतनी तेज क्यों है?

मैं Postgres में सभी प्रासंगिक स्तंभ पर सूचकांक बनाया है, तो यह एक बहुत निष्पक्ष तुलना की जानी चाहिए। पोस्टग्रेस में क्वेरी प्लान को देखते हुए हालांकि यह अभी भी एक इंडेक्स का उपयोग कर रहा था और फिर स्कैनिंग (मुझे लगता है क्योंकि यह सभी अलग-अलग इंडेक्स का उपयोग नहीं कर सका)।

जैसा कि मैं इसे समझता हूं, पोस्टग्रेस और सोलर अस्पष्ट समान डेटा संरचनाओं (बी-पेड़) का उपयोग करते हैं, और वे दोनों डेटा स्मृति में कैश करते हैं। तो मैं सोच रहा हूं कि इस तरह का एक बड़ा प्रदर्शन अंतर कहाँ से आता है।

आर्किटेक्चर में क्या अंतर यह समझाएगा?

+3

क्या आपने पोस्टग्रेस पूर्ण टेक्स्ट खोज या सरल 'पसंद' प्रश्नों का उपयोग किया था? –

+0

रिलेशनल मॉडल का कभी भी बदसूरत प्रश्नों पर अच्छा प्रदर्शन करने का इरादा नहीं था, जैसे 'मुझे उन सभी लोगों को दें जो बुधवार को पैदा हुए थे और 2003 और 2005 के बीच एक लाल कार के स्वामित्व में थे।' इसके लिए खोज इंजन (जैसे ल्यूसीन) हैं। इंडेक्स कभी-कभी मदद करते हैं, मेमोरी सेटिंग्स हमेशा मदद करते हैं। – wildplasser

+1

मैं आपके प्रश्न से थोड़ा उलझन में हूं, इसलिए मैं यहां पूछता हूं: http://dba.stackexchange.com/questions/34014/using-solr-lucene-for-searching-non-text-tables विल/ल्यूसीन PostgreSQL से खोज तेज हो सकती है भले ही कोई पूर्ण-पाठ खोज शामिल न हो? – alfonx

उत्तर

120

पहला, सोलर बी-पेड़ का उपयोग नहीं करता है। एक ल्यूसीन (सोलर द्वारा उपयोग की जाने वाली अंतर्निहित लाइब्रेरी) इंडेक्स केवल पढ़ने के लिए segments से बना है। प्रत्येक सेगमेंट के लिए, लुसीन एक शब्दकोष बनाए रखता है, जिसमें सेगमेंट में दिखाई देने वाली शर्तों की सूची होती है, लेक्सिकोोग्राफिक सॉर्ट किया जाता है। इस शब्दकोष शब्द में एक शब्द खोजना एक बाइनरी खोज का उपयोग करके किया जाता है, इसलिए एकल अवधि की लुकअप की लागत O(log(t)) है जहां टी शर्तों की संख्या है। इसके विपरीत, एक मानक आरडीबीएमएस लागत सूचकांक का उपयोग O(log(d)) जहां डी दस्तावेजों की संख्या है। जब कई दस्तावेज़ कुछ फ़ील्ड के लिए समान मूल्य साझा करते हैं, तो यह एक बड़ी जीत हो सकती है।

इसके अलावा, लुसेन कमिटर उवे स्किंडलर ने कुछ साल पहले बहुत ही प्रदर्शन numeric range queries के लिए समर्थन जोड़ा। numeric field के प्रत्येक मान के लिए, लुसेन विभिन्न मूल्यों के साथ कई मानों को संग्रहीत करता है। यह ल्यूसीन को रेंज पूछताछ को बहुत कुशलता से चलाने की अनुमति देता है। चूंकि आपका उपयोग-मामला संख्यात्मक सीमा प्रश्नों का लाभ उठाने लगता है, इसलिए यह समझा सकता है कि सौर इतना तेज क्यों है। (अधिक जानकारी के लिए, javadocs पढ़ें जो बहुत ही रोचक हैं और प्रासंगिक शोध पत्रों के लिंक देते हैं।)

लेकिन सौर केवल ऐसा ही कर सकता है क्योंकि इसमें आरडीबीएमएस की सभी बाधाएं नहीं हैं। उदाहरण के लिए, एक समय में एक ही दस्तावेज़ को अपडेट करने में सोलर बहुत खराब है (यह बैच अपडेट पसंद करता है)।

+4

ग्रेट उत्तर (पहला पैराग्राफ) +1। – Yavar

+2

हालांकि मेरे यहां कहने की एक बात है। जब आप कहते हैं "ल्यूसीन एक शब्दकोष बनाए रखता है, जिसमें सेगमेंट में दिखाई देने वाली शर्तों की सूची शामिल होती है, लेक्सिकोोग्राफिक सॉर्ट किया जाता है।" तो यदि शब्द शब्दावली से क्रमबद्ध हैं और यह ओ (लॉग टी) समय (बाइनरी खोज) लेता है जिसका अर्थ है कि शब्द किसी सरणी में संग्रहीत हैं? क्या यह सही है (मेरा मतलब है कि आपने इंडेक्स को संग्रहित करने के लिए एक संतुलित पेड़ संरचना को खारिज कर दिया है और हैश टेबल सीधे सॉर्ट किए गए इंडेक्स को स्टोर नहीं कर सकता है, इसलिए हम केवल 2 डी सरणी (शब्द के साथ, पोस्टिंग सूची में पॉइंटर को इसके तत्वों के रूप में) के साथ छोड़ दिया गया है, जिस पर बाइनरी खोज पर चलाया जाता है) – Yavar

+3

यहां जोड़ने की एक और बात यह है कि ल्यूसीन इंडेक्स बीटी नहीं है, हालांकि यह एक उलटा सूचकांक है (जैसे अधिकांश खोज इंजन)। आपका जवाब हालांकि मेरे लिए कुछ नया आया था। चूंकि मैं बैलेंस्ड ट्री स्ट्रक्चर को शर्तों को स्टोर करने की अपेक्षा कर रहा था (उस मामले में भी खोज लॉग (टी) होगी और प्रत्येक नोड में सूचियां पोस्ट करने के लिए पॉइंटर भी होगा। बैलेंस पेड़ के साथ हम लेक्सिकोग्राफिक सॉर्टेड शर्तों को भी बनाए रखने में सक्षम होंगे। – Yavar

1

कृपया this और this पढ़ें।

सोलर (लुसेन) inverted index बनाता है जहां डेटा पुनर्प्राप्त करना काफी तेज़ हो जाता है। I read कि PostgreSQL में भी इसी तरह की सुविधा है लेकिन यह सुनिश्चित नहीं है कि आपने इसका उपयोग किया था या नहीं।

आपके द्वारा देखे गए प्रदर्शन मतभेदों को "क्या खोजा जा रहा है" के लिए जिम्मेदार ठहराया जा सकता है, "उपयोगकर्ता प्रश्न क्या हैं?"

+0

धन्यवाद!वे बहुत दिलचस्प थे। मैं कुछ और तकनीकी के लिए उम्मीद कर रहा था हालांकि। सोलर के एक आर्किटेक्चर अवलोकन की तरह, या ऐसा कुछ। – cberner

+0

@Tejas: यहां तक ​​कि डेटाबेस उलटा इंडेक्स बना सकते हैं। इनवर्टेड इंडेक्स बनाने के लिए उन्हें क्या रोक रहा है? – Yavar

+0

यावार: मैंने यह नहीं कहा कि डेटाबेस उलटा इंडेक्स नहीं बना सकते हैं। असल में दूसरी पंक्ति में मैंने जीएनएन-इनवर्टेड इंडेक्स का उपयोग करके पोस्टग्रेएसक्यूएल के बारे में लिंक करने की ओर इशारा किया। एक और प्रकार है: जीआईएसटी (सामान्यीकृत सर्च ट्री) - पोस्टग्रेएसक्यूएल में आधारित इंडेक्स जो जीआईएन से धीमा है। @gberner द्वारा उपयोग किया जाने वाला वास्तविक अनुक्रमणिका प्रकार PostgreSQL के निम्न प्रदर्शन के लिए एक कारक होगा। –

5

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

जैसा कि आपको कोई संदेह नहीं है, सोलर दोनों की अनुक्रमणिका से डेटा को खोजने और पुनर्प्राप्त करने की क्षमता को सक्षम बनाता है। यह उत्तरार्द्ध (वैकल्पिक) क्षमता है जो प्राकृतिक प्रश्न की ओर ले जाती है ... "क्या मैं एक डेटाबेस के रूप में सोलर का उपयोग कर सकता हूं?"

जवाब एक योग्य है हाँ, और मैं निम्नलिखित का उल्लेख:

मेरा व्यक्तिगत राय है कि Solr का सबसे अच्छा सोचा है मेरे आवेदन और मेरे डेटाबेस में महारत हासिल डेटा के बीच एक खोजने योग्य कैश के रूप में। इस तरह मैं दोनों दुनिया के सर्वश्रेष्ठ मिलता है।

6

यह सबसे बड़ा अंतर यह है कि ल्यूसीन/सोलर इंडेक्स एक एकल-टेबल डेटाबेस की तरह है, बिना संबंध प्रश्नों (जॉइन) के लिए किसी भी समर्थन के। याद रखें कि एक सूचकांक आमतौर पर केवल खोज का समर्थन करने के लिए होता है और डेटा का प्राथमिक स्रोत नहीं होता है। तो आपका डेटाबेस "तीसरा सामान्य रूप" हो सकता है लेकिन सूचकांक पूरी तरह से डी-सामान्यीकृत हो जाएगा और इसमें ज्यादातर खोजे जाने वाले डेटा शामिल होंगे।

आम तौर पर डेटाबेस आंतरिक विखंडन से पीड़ित हैं, उन्हें भारी अनुरोधों पर बहुत अधिक अर्ध-यादृच्छिक I/O कार्यों को करने की आवश्यकता है।

इसका मतलब है, उदाहरण के लिए, डेटाबेस के इंडेक्स आर्किटेक्चर पर विचार करते हुए, क्वेरी इंडेक्स की ओर ले जाती है जो बदले में डेटा की ओर ले जाती है। यदि डेटा पुनर्प्राप्त करने के लिए व्यापक रूप से फैल गया है, तो परिणाम लंबा लगेगा और ऐसा लगता है कि डेटाबेस में क्या होता है।

35

आपने वास्तव में अपने PostgreSQL उदाहरण या आपके प्रश्नों को ट्यून करने के लिए क्या किया है, इसके बारे में बहुत कुछ नहीं कहा। ट्यूनिंग के माध्यम से PostgreSQL क्वेरी पर 50x की गति को देखना असामान्य नहीं है और/या बेहतर रूप से अनुकूलित प्रारूप में आपकी क्वेरी को पुन: स्थापित करना असामान्य नहीं है।

बस इस सप्ताह एक काम पर एक रिपोर्ट थी जिसमें किसी ने जावा और कई प्रश्नों का उपयोग करके लिखा था, जिस पर यह चार घंटों में कितना दूर था, लगभग पूरा होने में लगभग एक महीने लग रहा था। (इसे पांच अलग-अलग तालिकाओं को मारने की ज़रूरत होती है, जिनमें से प्रत्येक लाखों पंक्तियों के साथ होती है।) मैं इसे कई सीटीई और खिड़की के फ़ंक्शन का उपयोग करके फिर से लिखता हूं ताकि यह दस मिनट से भी कम समय में दौड़ सके और वांछित परिणाम सीधे क्वेरी से उत्पन्न हो सके। यह एक 4400x गति है।

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

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

-- Create the table. 
-- In reality, I would probably make tsv NOT NULL, 
-- but I'm keeping the example simple... 
CREATE TABLE war_and_peace 
    (
    lineno serial PRIMARY KEY, 
    linetext text NOT NULL, 
    tsv tsvector 
); 

-- Load from downloaded data into database. 
COPY war_and_peace (linetext) 
    FROM '/home/kgrittn/Downloads/war-and-peace.txt'; 

-- "Digest" data to lexemes. 
UPDATE war_and_peace 
    SET tsv = to_tsvector('english', linetext); 

-- Index the lexemes using GiST. 
-- To use GIN just replace "gist" below with "gin". 
CREATE INDEX war_and_peace_tsv 
    ON war_and_peace 
    USING gist (tsv); 

-- Make sure the database has statistics. 
VACUUM ANALYZE war_and_peace; 

अनुक्रमण के लिए स्थापित, मैं अनुक्रमित के दोनों प्रकार के साथ पंक्ति में गिना जाता है और समय के साथ कुछ खोजों को दिखाने:

-- Find lines with "gentlemen". 
EXPLAIN ANALYZE 
SELECT * FROM war_and_peace 
    WHERE tsv @@ to_tsquery('english', 'gentlemen'); 

84 पंक्तियाँ, सार: 2.006 एमएस, जिन: 0.194 एमएस

-- Find lines with "ladies". 
EXPLAIN ANALYZE 
SELECT * FROM war_and_peace 
    WHERE tsv @@ to_tsquery('english', 'ladies'); 

184 पंक्तियां, गीस्ट: 3.549 एमएस, जीन: 0।328 एमएस

-- Find lines with "ladies" and "gentlemen". 
EXPLAIN ANALYZE 
SELECT * FROM war_and_peace 
    WHERE tsv @@ to_tsquery('english', 'ladies & gentlemen'); 

1 पंक्ति, सार: 0.971 एमएस, जिन: 0.104 एमएस

अब, के बाद से जिन सूचकांक के बारे में 10 बार सार सूचकांक की तुलना में तेजी से आप आश्चर्य हो सकता है क्यों किसी को भी अनुक्रमण के लिए सार का उपयोग होता था पाठ डेटा जवाब यह है कि जीआईएसटी आमतौर पर बनाए रखने के लिए तेज़ है। इसलिए यदि आपका टेक्स्ट डेटा बेहद अस्थिर है तो जीआईएसटी इंडेक्स कुल भार पर जीत सकता है, जबकि जीआईएन इंडेक्स जीत जाएगा यदि आप केवल खोज समय में रुचि रखते हैं या ज्यादातर पढ़ने के लिए वर्कलोड के लिए।

सूचकांक के बिना उपर्युक्त प्रश्न 17.943 एमएस से 23.3 9 7 एमएस तक कहीं भी लेते हैं क्योंकि उन्हें पूरी तालिका को स्कैन करना होगा और प्रत्येक पंक्ति पर एक मैच की जांच करनी होगी।

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

सेटअप, निश्चित रूप से, एक बार की बात है। tsv कॉलम को बनाए रखने के लिए ट्रिगर के साथ, किसी भी बदलाव को तुरंत किसी भी सेटअप को दोबारा बिना खोजे जा सकेंगे।

धीमी PostgreSQL क्वेरी के साथ, यदि आप टेबल संरचना (इंडेक्स सहित), समस्या क्वेरी और आउटपुट को EXPLAIN ANALYZE चलाने से आउटपुट दिखाते हैं, तो कोई भी लगभग हमेशा समस्या को खोज सकता है और सुझाव देता है कि इसे कैसे चलाने के लिए और तेज।


अद्यतन (दिसम्बर 9 '16)

मैं क्या मैं पहले समय प्राप्त करने के लिए प्रयोग किया जाता है, लेकिन आज यह शायद 9.2 प्रमुख रिलीज़ हो गया होता के आधार पर उल्लेख नहीं किया। मैं बस इस पुराने धागे में हुआ और संस्करण 9.6.1 का उपयोग करके उसी हार्डवेयर पर फिर से कोशिश की, यह देखने के लिए कि हस्तक्षेप प्रदर्शन ट्यूनिंग में से कोई भी इस उदाहरण में मदद करता है। केवल एक तर्क के लिए प्रश्न केवल 2% के प्रदर्शन में वृद्धि हुई है, लेकिन जीआईएन (उलटा) का उपयोग करते समय "महिलाओं" और "सज्जनों" की गति में दोगुना होकर 0.053 एमएस (यानी, 53 माइक्रोसॉन्ड) तक दोगुना हो गया है। सूचकांक।

+4

ध्यान दें कि जीआईएसटी अब बनाए रखने के लिए इतना तेज़ नहीं है, सीएफ। http://blog.pgaddict.com/posts/performance-since-postgresql-7-4-to-9-4-fulltext – ArtemGr

संबंधित मुद्दे