मैं Ubuntu 12.04 पर PostgreSQL 9.1 का उपयोग करता हूं।
मुझे समय की सीमा के भीतर रिकॉर्ड का चयन करने की आवश्यकता है: मेरी तालिका time_limits
में दो timestamp
फ़ील्ड और एक integer
संपत्ति है। मेरी वास्तविक तालिका में अतिरिक्त कॉलम हैं जो इस क्वेरी के साथ शामिल नहीं हैं।
create table (
start_date_time timestamp,
end_date_time timestamp,
id_phi integer,
primary key(start_date_time, end_date_time,id_phi);
इस तालिका में लगभग 2M रिकॉर्ड हैं।
निम्नलिखित की तरह क्वेरीज़ ने भारी मात्रा में समय लिया:
select * from time_limits as t
where t.id_phi=0
and t.start_date_time <= timestamp'2010-08-08 00:00:00'
and t.end_date_time >= timestamp'2010-08-08 00:05:00';
इसलिए मैंने एक और सूचकांक जोड़ने की कोशिश की - पीके का विलोम:
create index idx_inversed on time_limits(id_phi, start_date_time, end_date_time);
मुझे यह आभास हुआ कि प्रदर्शन में सुधार हुआ है: तालिका के मध्य में रिकॉर्ड तक पहुंचने का समय अधिक उचित प्रतीत होता है: कहीं 40 से 90 सेकंड के बीच।
लेकिन यह अभी भी समय सीमा के बीच में मूल्यों के लिए कई दसियों सेकंड है। और तालिका के अंत को लक्षित करते समय दो बार और अधिक (कालानुक्रमिक रूप से बोलना)।
मैंने explain analyze
पहली बार इस क्वेरी प्लान को प्राप्त करने की कोशिश की :
Bitmap Heap Scan on time_limits (cost=4730.38..22465.32 rows=62682 width=36) (actual time=44.446..44.446 rows=0 loops=1)
Recheck Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
-> Bitmap Index Scan on idx_time_limits_phi_start_end (cost=0.00..4714.71 rows=62682 width=0) (actual time=44.437..44.437 rows=0 loops=1)
Index Cond: ((id_phi = 0) AND (start_date_time <= '2011-08-08 00:00:00'::timestamp without time zone) AND (end_date_time >= '2011-08-08 00:05:00'::timestamp without time zone))
Total runtime: 44.507 ms
मैं खोज को अनुकूलित करने के लिए क्या कर सकता था? एक बार id_phi
सेट होने पर आप दो टाइमस्टैम्प कॉलम को स्कैन करते हुए बिताए गए सभी समय देख सकते हैं 0
। और मैं टाइमस्टैम्प पर बड़े स्कैन (60K पंक्तियों!) को नहीं समझता। क्या वे प्राथमिक कुंजी द्वारा अनुक्रमित नहीं हैं और idx_inversed
मैंने जोड़ा है?
क्या मुझे टाइमस्टैम्प प्रकार से कुछ और में बदलना चाहिए?
मैंने GIST और GIN इंडेक्स के बारे में थोड़ा पढ़ा है। मैं इकट्ठा करता हूं कि वे कस्टम प्रकारों के लिए कुछ शर्तों पर अधिक कुशल हो सकते हैं। क्या यह मेरे उपयोग के मामले के लिए एक व्यवहार्य विकल्प है?
explain analyze
आउटपुट में रिपोर्ट किया गया समय सर्वर पर आवश्यक क्वेरी है । यदि आपकी क्वेरी 45 सेकंड लेती है, तो अतिरिक्त समय डेटाबेस से प्रोग्राम को क्वेरी चलाने वाले प्रोग्राम में डेटा ट्रांसफर करने में व्यतीत होता है। आखिरकार यह 62682 पंक्तियाँ हैं और यदि प्रत्येक पंक्ति बड़ी है (उदाहरण के लिए लंबी varchar
या text
कॉलम), तो यह ट्रांसफर टाइम को प्रभावित कर सकती है। काफी।
rows=62682 rows
योजनाकार का अनुमान है । क्वेरी 0 पंक्तियों को देती है। (actual time=44.446..44.446 rows=0 loops=1)