क्या डेटा के साथ तालिका भरने से पहले एक इंडेक्स बनाना बेहतर है, या डेटा के लागू होने के बाद?


87

मेरे पास लगभग 100 मीटर पंक्तियों की एक तालिका है जिसे मैं एक अनुक्रमणिका को जोड़ने के लिए कॉपी करने जा रहा हूं। नई तालिका बनाने में लगने वाले समय के साथ मैं इतना चिंतित नहीं हूं, लेकिन यदि मैं किसी भी डेटा को डालने से पहले तालिका को बदल देता हूं या पहले डेटा सम्मिलित करता हूं और फिर सूचकांक को जोड़ता हूं तो क्या बनाया गया सूचकांक अधिक कुशल होगा?

जवाबों:


113

डेटा डालने के बाद इंडेक्स बनाना अधिक कुशल तरीका है (इसे अक्सर बैच आयात से पहले इंडेक्स छोड़ने के लिए फिर से आयात किया जाता है और आयात के बाद इसे फिर से बनाया जाता है)।

सिंथेटिक उदाहरण (PostgreSQL 9.1, धीमी विकास मशीन, एक मिलियन पंक्तियाँ):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

सम्मिलित करें और फिर इंडेक्स बनाएं - लगभग 12 सेकंड

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

सूचकांक बनाएं और फिर डालें - लगभग 25.5 सेकंड (दो बार से अधिक धीमा)


5
+1, इंडेक्स स्पष्ट रूप से 100M पंक्ति सम्मिलित करने वाले कार्य को धीमा कर देगा, इसलिए उन्हें छोड़ना और उन्हें पुनः बनाना बेहतर होगा।
23:

10

पंक्तियों को जोड़ने के बाद सूचकांक बनाने के लिए शायद बेहतर है। न केवल यह तेज होगा, बल्कि पेड़ संतुलन बेहतर होगा।

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


2

यह इस समस्या पर कोई फर्क नहीं पड़ता क्योंकि:

  1. यदि आप तालिका में पहले डेटा जोड़ते हैं और इसके बाद आप इंडेक्स जोड़ते हैं। आपका अनुक्रमणिका जनरेट करने का समय O(n*log(N))लंबा होगा (जहाँ nएक पंक्तियाँ जोड़ी गई हैं)। क्योंकि ट्री जेरेटिंग टाइम O(N*log(N))तब है जब आप इसे पुराने डेटा में विभाजित करते हैं और आपके द्वारा प्राप्त किए गए नए डेटा O((X+n)*log(N))को बस में परिवर्तित किया जा सकता हैO(X*log(N) + n*log(N)) और इस प्रारूप में आप बस देख सकते हैं कि आप क्या अतिरिक्त प्रतीक्षा करेंगे।
  2. यदि आप सूचकांक जोड़ते हैं और इसके बाद डेटा डालते हैं। हर पंक्ति (आपके पास nनई पंक्तियाँ हैं) आपको O(log(N))पेड़ की संरचना को पुनर्जीवित करने के लिए अतिरिक्त समय लगाने की आवश्यकता है, इसमें नया तत्व जोड़ने के बाद (नई पंक्ति से अनुक्रमणिका स्तंभ, क्योंकि सूचकांक पहले से मौजूद है और नई पंक्ति जोड़ दी गई थी, तब सूचकांक को संतुलित करने के लिए पुनर्जीवित किया जाना चाहिए संरचना, यह लागत O(log(P))जहां Pएक सूचकांक शक्ति [सूचकांक में तत्व] ) है। आपके पास nनई पंक्तियाँ हैं और अंत में आपके पास n * O(log(N))फिर O(n*log(N))अतिरिक्त समय है।

1

अधिकांश मामलों में बहुत तेजी के बाद बनाए गए सूचकांक। बिंदु में मामला: varchar (255) पर पूर्ण पाठ के साथ 20 मिलियन पंक्तियाँ - (व्यवसाय नाम) सूचकांक पंक्तियों को आयात करते समय - सबसे खराब मामलों में 20 सेकंड तक लेने के खिलाफ एक मैच। ड्रॉप इंडेक्स और री-क्रिएट - हर बार 1 सेकंड से कम समय लेने के खिलाफ मैच


-2

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.