क्या पोस्टग्रेज़ में एक विशिष्ट जॉइन ऑर्डर को मजबूर करने का कोई तरीका है?पोस्टग्रेज़ में तालिका में शामिल होने के लिए
मुझे एक ऐसा प्रश्न है जो इस तरह दिखता है। मैंने वास्तविक सामग्री में मौजूद सामानों का एक गुच्छा समाप्त कर दिया है, लेकिन यह सरलीकरण इस मुद्दे को प्रदर्शित करता है। जो बचा है वह बहुत ही गूढ़ नहीं होना चाहिए: भूमिका/कार्य सुरक्षा प्रणाली का उपयोग करके, मैं यह निर्धारित करने की कोशिश कर रहा हूं कि किसी दिए गए उपयोगकर्ता को दिए गए कार्य को करने के लिए विशेषाधिकार हैं या नहीं।
select task.taskid
from userlogin
join userrole using (userloginid)
join roletask using (roleid)
join task using (taskid)
where loginname='foobar'
and taskfunction='plugh'
लेकिन मैंने महसूस किया कि कार्यक्रम पहले से ही USERLOGIN का मूल्य जानता है, तो यह USERLOGIN पर देखने को छोड़ने और सिर्फ userloginid भरते हुए, इस तरह से लग रहा था क्वेरी और अधिक कुशल बनाया जा सकता है:
select task.taskid
from userrole
join roletask using (roleid)
join task using (taskid)
where userloginid=42
and taskfunction='plugh'
जब मैंने ऐसा किया - क्वेरी से एक तालिका को समाप्त करना और उस तालिका से पुनर्प्राप्त मूल्य को हार्ड-कोडिंग करना - समझाया गया योजना का समय बढ़ गया! मूल क्वेरी में, पोस्टग्रेज़ उपयोगकर्ता लॉगिन को पढ़ते हैं, फिर userrole तो फिर कार्यलेट roletask। लेकिन नई पूछताछ में, उसने पहले roletask पढ़ने का फैसला किया, और उसके बाद userrole में शामिल हो गए, भले ही इसे roletask पर एक पूर्ण फ़ाइल स्कैन करने की आवश्यकता हो।
पूर्ण समझाने की योजना है:
संस्करण 1:
Hash Join (cost=12.79..140.82 rows=1 width=8)
Hash Cond: (roletask.taskid = task.taskid)
-> Nested Loop (cost=4.51..129.73 rows=748 width=8)
-> Nested Loop (cost=4.51..101.09 rows=12 width=8)
-> Index Scan using idx_userlogin_loginname on userlogin (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((loginname)::text = 'foobar'::text)
-> Bitmap Heap Scan on userrole (cost=4.51..92.41 rows=33 width=16)
Recheck Cond: (userrole.userloginid = userlogin.userloginid)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.50 rows=33 width=0)
Index Cond: (userrole.userloginid = userlogin.userloginid)
-> Index Scan using idx_roletask_role on roletask (cost=0.00..1.50 rows=71 width=16)
Index Cond: (roletask.roleid = userrole.roleid)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)
संस्करण 2:
Hash Join (cost=96.58..192.82 rows=4 width=8)
Hash Cond: (roletask.roleid = userrole.roleid)
-> Hash Join (cost=8.28..104.10 rows=9 width=16)
Hash Cond: (roletask.taskid = task.taskid)
-> Seq Scan on roletask (cost=0.00..78.35 rows=4635 width=16)
-> Hash (cost=8.27..8.27 rows=1 width=8)
-> Index Scan using idx_task_taskfunction on task (cost=0.00..8.27 rows=1 width=8)
Index Cond: ((taskfunction)::text = 'plugh'::text)
-> Hash (cost=87.92..87.92 rows=31 width=8)
-> Bitmap Heap Scan on userrole (cost=4.49..87.92 rows=31 width=8)
Recheck Cond: (userloginid = 42)
-> Bitmap Index Scan on idx_userrole_login (cost=0.00..4.49 rows=31 width=0)
Index Cond: (userloginid = 42)
(हाँ, मुझे पता है कि दोनों ही मामलों में लागत कम है और अंतर नहीं करता है कि ऐसा लगता है कि इससे कोई फर्क नहीं पड़ता। लेकिन यह है कि मैंने जो पोस्ट करना है उसे सरल बनाने के लिए क्वेरी से अतिरिक्त काम का एक गुच्छा समाप्त कर दिया। असली सवाल अभी भी अपमानजनक नहीं है, लेकिन मुझे टी में अधिक दिलचस्पी है । वह सिद्धांत)
क्या आप क्वेरी योजनाएं (विश्लेषण समझाएं) और तालिका परिभाषाएं दिखा सकते हैं? – hgmnz
ठीक है, आपने पूछा, मैंने वास्तविक क्वेरी के साथ काल्पनिक सरल उदाहरण को प्रतिस्थापित किया, और योजना परिणामों को समझाया। ओह, मुझे यकीन है कि मैं दूसरी क्वेरी को तेज करने के लिए कुछ अतिरिक्त इंडेक्स जोड़ सकता हूं, लेकिन यह बात नहीं है। पोस्टग्रेस ने ऐसी योजना क्यों चुनी जो कि सबसे अच्छा था, जो कि यह कर सकता था, उसके प्रश्नों के मुताबिक? खासकर जब यह दिखाया गया कि अगर मैं क्वेरी को अधिक जटिल बना देता तो बेहतर हो सकता है? – Jay
क्या आप प्रश्नों के वास्तविक रन समय की तुलना कर रहे हैं या सिर्फ व्याख्या योजना में शीर्षक लागत देख रहे हैं? मूल्य? विशेष रूप से, आपने अभी विश्लेषण की व्याख्या नहीं की है, आउटपुट समझाया है। यद्यपि आप एक धीमी क्वेरी चलाने के बराबर उच्च लागत की अपेक्षा करेंगे, यह शायद इस तरह से काम न करे। – araqnid