जवाबों:
PostgreSQL के पास शुरू में एक डेटाबेस को सर्वश्रेष्ठ रूप से आबाद करने के बारे में एक गाइड है , और वे थोक लोडिंग पंक्तियों के लिए COPY कमांड का उपयोग करने का सुझाव देते हैं। गाइड के पास प्रक्रिया को तेज करने के कुछ अन्य अच्छे सुझाव हैं, जैसे डेटा लोड करने से पहले अनुक्रमित और विदेशी कुंजियों को निकालना (और बाद में उन्हें वापस जोड़ना)।
COPY का उपयोग करने के लिए एक विकल्प है, जो मल्टीग्रो वैल्यू सिंटैक्स है जो पोस्टग्रैज का समर्थन करता है। से प्रलेखन :
INSERT INTO films (code, title, did, date_prod, kind) VALUES
('B6717', 'Tampopo', 110, '1985-02-10', 'Comedy'),
('HG120', 'The Dinner Game', 140, DEFAULT, 'Comedy');
उपरोक्त कोड दो पंक्तियों को सम्मिलित करता है, लेकिन आप इसे मनमाने ढंग से बढ़ा सकते हैं, जब तक कि आप तैयार स्टेटमेंट टोकन की अधिकतम संख्या को हिट न करें (यह $ 999 हो सकता है, लेकिन मैं इसके बारे में 100% निश्चित नहीं हूं)। कभी-कभी कोई COPY का उपयोग नहीं कर सकता है, और यह उन स्थितियों के लिए एक योग्य प्रतिस्थापन है।
चीजों को गति देने का एक तरीका स्पष्ट रूप से कई आवेषण करना है या एक लेनदेन के भीतर कॉपी करना है (1000 का कहना है)। पोस्टग्रेज का डिफ़ॉल्ट व्यवहार प्रत्येक कथन के बाद करना है, इसलिए कमिट्स को बैच कर, आप कुछ ओवरहेड से बच सकते हैं। जैसा कि डैनियल के उत्तर में गाइड कहता है, आपको काम करने के लिए ऑटोकॉमिट को निष्क्रिय करना पड़ सकता है। नीचे दिए गए टिप्पणी पर भी ध्यान दें जो कि Wal_buffers के आकार को 16 MB तक बढ़ाने का सुझाव देता है।
UNNEST
सरणियों के साथ फ़ंक्शन का उपयोग मल्टीरो वैल्यू सिंटैक्स के साथ किया जा सकता है। मुझे लगता है कि इस पद्धति का उपयोग की तुलना में धीमी कर रहा हूँ COPY
, लेकिन यह psycopg और अजगर के साथ काम करने में मेरे लिए उपयोगी है (अजगर list
पारित कर दिया करने के लिए cursor.execute
स्नातकोत्तर हो जाता है ARRAY
):
INSERT INTO tablename (fieldname1, fieldname2, fieldname3)
VALUES (
UNNEST(ARRAY[1, 2, 3]),
UNNEST(ARRAY[100, 200, 300]),
UNNEST(ARRAY['a', 'b', 'c'])
);
VALUES
अतिरिक्त अस्तित्व की जाँच के साथ subselect का उपयोग किए बिना :
INSERT INTO tablename (fieldname1, fieldname2, fieldname3)
SELECT * FROM (
SELECT UNNEST(ARRAY[1, 2, 3]),
UNNEST(ARRAY[100, 200, 300]),
UNNEST(ARRAY['a', 'b', 'c'])
) AS temptable
WHERE NOT EXISTS (
SELECT 1 FROM tablename tt
WHERE tt.fieldname1=temptable.fieldname1
);
बल्क अपडेट के लिए समान सिंटैक्स:
UPDATE tablename
SET fieldname1=temptable.data
FROM (
SELECT UNNEST(ARRAY[1,2]) AS id,
UNNEST(ARRAY['a', 'b']) AS data
) AS temptable
WHERE tablename.id=temptable.id;
आप उपयोग कर सकते हैं COPY table TO ... WITH BINARY
जो " पाठ और सीएसवी प्रारूपों की तुलना में कुछ तेज है ।" केवल तभी करें जब आपके पास सम्मिलित करने के लिए लाखों पंक्तियाँ हों, और यदि आप बाइनरी डेटा के साथ सहज हैं।
बाइनरी इनपुट के साथ psycopg2 का उपयोग करके पायथन में एक उदाहरण नुस्खा है ।
यह ज्यादातर डेटाबेस में (अन्य) गतिविधि पर निर्भर करता है। इस तरह के संचालन प्रभावी रूप से अन्य सत्रों के लिए पूरे डेटाबेस को फ्रीज करते हैं। एक अन्य विचार डेटामॉडल और बाधाओं, ट्रिगर आदि की उपस्थिति है।
मेरा पहला दृष्टिकोण हमेशा है: लक्ष्य तालिका के समान संरचना वाला एक (अस्थायी) तालिका बनाएं (तालिका tmp AS चुनें * लक्ष्य से जहां 1 = 0), और फ़ाइल को अस्थायी तालिका में पढ़कर प्रारंभ करें। फिर मैं जांचता हूं कि क्या जांचा जा सकता है: डुप्लिकेट, चाबियाँ जो पहले से ही लक्ष्य में मौजूद हैं, आदि।
तो मैं बस एक "लक्ष्य में सम्मिलित करें चयन * tmp से" या इसी तरह करते हैं।
यदि यह विफल हो जाता है, या बहुत लंबा हो जाता है, तो मैं इसे निरस्त करता हूं और अन्य तरीकों (अस्थायी रूप से अनुक्रमित / बाधाएं, आदि को छोड़ने) पर विचार करता हूं।
मैंने मूल लीबपैक विधियों के साथ बहुत तेजी से पोस्टग्रैस्क डेटा लोडर लागू किया। मेरा पैकेज आज़माएं https://www.nuget.org/packages/NpgsqlBulkCopy/
मुझे बस इस मुद्दे का सामना करना पड़ा और Postgres को थोक आयात के लिए csvsql ( रिलीज ) की सिफारिश करेगा । बल्क इंसर्ट करने के लिए आप बस createdb
और फिर उपयोग कर सकते हैं csvsql
, जो आपके डेटाबेस से जुड़ता है और CSV के संपूर्ण फ़ोल्डर के लिए अलग-अलग टेबल बनाता है।
$ createdb test
$ csvsql --db postgresql:///test --insert examples/*.csv
"बल्क डेटा" शब्द "बहुत सारे डेटा" से संबंधित है, इसलिए मूल कच्चे डेटा का उपयोग करना स्वाभाविक है , इसे एसक्यूएल में बदलने की आवश्यकता नहीं है। "बल्क इंसर्ट" के लिए विशिष्ट कच्चे डेटा फाइलें CSV और JSON हैं फॉर्मेट हैं।
में ईटीएल अनुप्रयोगों और घूस प्रक्रियाओं, हम इसे डालने से पहले डेटा को बदलने की जरूरत है। अस्थायी तालिका में (बहुत अधिक) डिस्क स्थान की खपत होती है, और यह इसे करने का सबसे तेज़ तरीका नहीं है। PostgreSQL विदेशी डेटा आवरण (FDW) सबसे अच्छा विकल्प है।
CSV का उदाहरण । मान लीजिए tablename (x, y, z)
एसक्यूएल और एक सीएसवी फ़ाइल की तरह
fieldname1,fieldname2,fieldname3
etc,etc,etc
... million lines ...
आप COPY
लोड करने के लिए क्लासिक एसक्यूएल का उपयोग कर सकते हैं ( जैसा कि मूल डेटा है) tmp_tablename
, वे फ़िल्टर्ड डेटा सम्मिलित करते हैं tablename
... लेकिन, डिस्क की खपत से बचने के लिए, सबसे अच्छा है सीधे द्वारा निगलना
INSERT INTO tablename (x, y, z)
SELECT f1(fieldname1), f2(fieldname2), f3(fieldname3) -- the transforms
FROM tmp_tablename_fdw
-- WHERE condictions
;
आपको FDW के लिए डेटाबेस तैयार करने की आवश्यकता है, और इसके बजाय स्थैतिक tmp_tablename_fdw
आप एक फ़ंक्शन का उपयोग कर सकते हैं जो इसे उत्पन्न करता है :
CREATE EXTENSION file_fdw;
CREATE SERVER import FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE tmp_tablename_fdw(
...
) SERVER import OPTIONS ( filename '/tmp/pg_io/file.csv', format 'csv');
JSON उदाहरण । दो फाइलों का एक सेट myRawData1.json
और Ranger_Policies2.json
इसके द्वारा निगला जा सकता है:
INSERT INTO tablename (fname, metadata, content)
SELECT fname, meta, j -- do any data transformation here
FROM jsonb_read_files('myRawData%.json')
-- WHERE any_condiction_here
;
जहाँ फंक्शन jsonb_read_files () मास्क द्वारा परिभाषित फ़ोल्डर की सभी फाइलों को पढ़ता है:
CREATE or replace FUNCTION jsonb_read_files(
p_flike text, p_fpath text DEFAULT '/tmp/pg_io/'
) RETURNS TABLE (fid int, fname text, fmeta jsonb, j jsonb) AS $f$
WITH t AS (
SELECT (row_number() OVER ())::int id,
f as fname,
p_fpath ||'/'|| f as f
FROM pg_ls_dir(p_fpath) t(f)
WHERE f like p_flike
) SELECT id, fname,
to_jsonb( pg_stat_file(f) ) || jsonb_build_object('fpath',p_fpath),
pg_read_file(f)::jsonb
FROM t
$f$ LANGUAGE SQL IMMUTABLE;
"फ़ाइल अंतर्ग्रहण" (मुख्य डेटा में मुख्य रूप से) के लिए सबसे लगातार विधि गज़िप प्रारूप पर मूल फ़ाइल को संरक्षित कर रही है और इसे स्ट्रीमिंग एल्गोरिथ्म के साथ स्थानांतरित कर रही है , कुछ भी जो तेजी से और बिना डिस्क पाइप में डिस्क खपत के बिना चल सकता है:
gunzip remote_or_local_file.csv.gz | convert_to_sql | psql
तो आदर्श (भविष्य) प्रारूप के लिए एक सर्वर विकल्प है .csv.gz
।