प्रश्न बिल्कुल समान नहीं हैं
संदर्भ को स्पष्ट करने के लिए:
max(id)
NULL
. को शामिल नहीं करता है मूल्य। लेकिनORDER BY ... LIMIT 1
नहीं।NULL
मान आरोही क्रम में अंतिम क्रमबद्ध होते हैं, और पहले अवरोही क्रम में। तो एकIndex Scan Backward
सबसे बड़ा मान नहीं मिल सकता है (max()
. के अनुसार) ) पहले, लेकिन किसी भी संख्या मेंNULL
मान।
के औपचारिक समकक्ष:
SELECT max(id) FROM testview;
नहीं है:
SELECT id FROM testview ORDER BY id DESC LIMIT 1;
लेकिन:
SELECT id FROM testview ORDER BY id DESC NULLS LAST LIMIT 1;
बाद वाली क्वेरी को तेज़ क्वेरी योजना नहीं मिलती है। लेकिन यह मेल खाने वाले क्रम के साथ एक इंडेक्स के साथ होगा:(id DESC NULLS LAST)
।
यह कुल कार्यों के लिए अलग है min()
और max()
. तालिका test1
. को लक्षित करते समय उन्हें एक तेज़ योजना मिलती है (id)
. पर सीधे सादे PK इंडेक्स का उपयोग करना . लेकिन जब दृश्य के आधार पर नहीं (या अंतर्निहित जॉइन-क्वेरी सीधे - दृश्य अवरोधक नहीं है)। NULL मानों को सही जगह पर सॉर्ट करने वाले इंडेक्स का शायद ही कोई प्रभाव पड़ता है।
हम पता है कि id
इस क्वेरी में कभी भी NULL
नहीं हो सकता है . कॉलम परिभाषित किया गया है NOT NULL
. और दृश्य में शामिल होना प्रभावी रूप से एक INNER JOIN
है जो NULL
. का परिचय नहीं दे सकता id
. के लिए मान .
हम यह भी जान लें कि test.id
. पर अनुक्रमणिका NULL मान नहीं हो सकते।
लेकिन पोस्टग्रेज़ क्वेरी प्लानर AI नहीं है। (न ही ऐसा होने की कोशिश करता है, जो जल्दी हाथ से निकल जाए।) मुझे दो कमियां दिखाई दे रही हैं :
min()
औरmax()
केवल तालिका को लक्षित करते समय तेज़ योजना प्राप्त करें, अनुक्रमणिका क्रम की परवाह किए बिना, एक अनुक्रमणिका शर्त जोड़ी जाती है:Index Cond: (id IS NOT NULL)
ORDER BY ... LIMIT 1
फ़ास्ट प्लान केवल सटीक मिलान वाले इंडेक्स सॉर्ट ऑर्डर के साथ प्राप्त करता है।
निश्चित नहीं है कि क्या इसमें सुधार किया जा सकता है (आसानी से)।
db<>fiddle यहां - उपरोक्त सभी को प्रदर्शित करना
सूचकांक
यह सूचकांक पूरी तरह से बेकार है:
CREATE INDEX ON "test" ("id");
PK test.id
. पर कॉलम पर एक अद्वितीय अनुक्रमणिका के साथ कार्यान्वित किया जाता है, जो पहले से ही वह सब कुछ शामिल करता है जो अतिरिक्त अनुक्रमणिका आपके लिए कर सकती है।
और भी बहुत कुछ हो सकता है, प्रश्न के स्पष्ट होने की प्रतीक्षा में।
विकृत परीक्षण केस
सार्थक होने के लिए परीक्षण मामला वास्तविक उपयोग के मामले से बहुत दूर है।
परीक्षण सेटअप में, प्रत्येक तालिका में 100k पंक्तियाँ होती हैं, इस बात की कोई गारंटी नहीं है कि joincol
में प्रत्येक मान दूसरी तरफ एक मैच है, और दोनों कॉलम NULL हो सकते हैं
आपके वास्तविक मामले में table1
. में 10M पंक्तियाँ हैं और table2
में <100 पंक्तियां , table1.joincol
. में प्रत्येक मान table2.joincol
. में एक मैच है , दोनों परिभाषित हैं NOT NULL
, और table2.joincol
अनोखा है। एक शास्त्रीय एक-से-अनेक संबंध। एक UNIQUE
होना चाहिए table2.joincol
. पर बाधा और एक FK बाधा t1.joincol --> t2.joincol
।
लेकिन फिलहाल यह सब सवालों में उलझा हुआ है। जब तक यह साफ नहीं हो जाता तब तक खड़े रहना।