मैं यह दिखाने के लिए एक नमूना क्वेरी योजना तैयार करने की कोशिश कर रहा हूं कि दो परिणाम सेटों का उपयोग करना या एक JOIN क्लॉज में उपयोग करने से बेहतर क्यों हो सकता है। मेरे द्वारा लिखी गई एक क्वेरी योजना ने मुझे स्टम्प किया है। मैं StackOverflow डेटाबेस का उपयोग Users.Reputation पर एक गैर-अनुक्रमित सूचकांक के साथ कर रहा हूँ।
CREATE NONCLUSTERED INDEX IX_NC_REPUTATION ON dbo.USERS(Reputation)
SELECT DISTINCT Users.Id
FROM dbo.Users
INNER JOIN dbo.Posts
ON Users.Id = Posts.OwnerUserId
OR Users.Id = Posts.LastEditorUserId
WHERE Users.Reputation = 5
क्वेरी प्लान https://www.brentozar.com/pastetheplan/?id=BkpZU1MZE पर है , मेरे लिए क्वेरी अवधि 4:37 मिनट, 26612 पंक्तियाँ वापस आ गईं।
मैंने किसी मौजूदा टेबल से निरंतर-स्कैन की इस शैली को पहले नहीं देखा है - मैं इस बात से अपरिचित हूं कि हर एक पंक्ति के लिए एक निरंतर स्कैन क्यों होता है, जब उपयोगकर्ता द्वारा इनपुट की गई एकल पंक्ति के लिए आमतौर पर एक निरंतर स्कैन का उपयोग किया जाता है उदाहरण के लिए सेलेक्ट गेटेट () चुनें। इसका उपयोग यहाँ क्यों किया जाता है? मैं वास्तव में इस क्वेरी योजना को पढ़ने में कुछ मार्गदर्शन की सराहना करूंगा।
अगर मैं इसे अलग करता हूं या UNION में विभाजित करता हूं, तो यह 12 सेकंड में चलने वाली एक मानक योजना बनाता है जिसमें 26612 पंक्तियां वापस आती हैं।
SELECT Users.Id
FROM dbo.Users
INNER JOIN dbo.Posts
ON Users.Id = Posts.OwnerUserId
WHERE Users.Reputation = 5
UNION
SELECT Users.Id
FROM dbo.Users
INNER JOIN dbo.Posts
ON Users.Id = Posts.LastEditorUserId
WHERE Users.Reputation = 5
मैं इस योजना की व्याख्या इस प्रकार कर रहा हूं:
- सभी 41782500 पंक्तियों को पोस्ट से प्राप्त करें (पंक्तियों की वास्तविक संख्या पोस्ट पर CI स्कैन से मेल खाती है)
- पोस्ट में प्रत्येक 41782500 पंक्तियों के लिए:
- स्केलर का उत्पादन करें:
- Expr1005: OwnerUserId
- Expr1006: OwnerUserId
- Expr1004: स्थिर मूल्य 62
- Expr1008: LastEditorUserId
- Expr1009: LastEditorUserId
- Expr1007: स्थिर मूल्य 62
- संघात में:
- Exp1010: यदि Expr1005 (OwnerUserId) शून्य नहीं है, तो उस अन्य का उपयोग करें Expr1008 (LastEditorUserID) का उपयोग करें
- Expr1011: यदि Expr1006 (OwnerUserId) शून्य नहीं है, तो उसका उपयोग करें, अन्यथा Expr1009 (LastEditorUserId) का उपयोग करें
- Expr1012: अगर Expr1004 (62) शून्य उपयोग है, तो Expr1007 (62) का उपयोग करें
- गणना स्केलर में: मुझे नहीं पता कि एक एम्परसेंड क्या करता है।
- Expr1013: 4 [और?] 62 (Expr1012) = 4 और OwnerUserId IS NULL (NULL = Expr1010) है
- Expr1014: 4 [और?] 62 (Expr1012)
- Expr1015: 16 और 62 (Expr1012)
- द्वारा क्रम में द्वारा:
- Expr1013 Desc
- Expr1014 Asc
- Expr1010 Asc
- Expr1015 उतर
- मर्ज इंटरवल में यह Expr1013 और Expr1015 को हटा दिया (ये इनपुट हैं, लेकिन आउटपुट नहीं हैं)
- नेस्टेड लूप के नीचे इंडेक्स की तलाश में यह शामिल है कि Expr1010 और Expr1011 का उपयोग विधेय की तलाश के रूप में किया जा रहा है, लेकिन मुझे यह समझ में नहीं आता है कि जब यह नेस्टेड लूप IX_NC_REPREATION से एक्सप्रि 1 और Expr1011 युक्त सबट्री से जुड़ता नहीं है, तो इन तक इसकी पहुंच कैसे होती है। ।
- नेस्टेड लूप्स केवल उन यूजर्स से जुड़ते हैं, जिनके पास पहले के सबट्री में मैच होता है। विधेय पुशडेक के कारण, IX_NC_REPUTATION पर अनुक्रमणिका की तलाश से लौटी सभी पंक्तियाँ वापस आ जाती हैं।
- अंतिम नेस्टेड लूप शामिल होते हैं: प्रत्येक पोस्ट रिकॉर्ड के लिए, Users.d आउटपुट करते हैं, जहां नीचे डेटासेट में एक मैच पाया जाता है।
SELECT Users.Id FROM dbo.Users WHERE Users.Reputation = 5 AND EXISTS (SELECT 1 FROM dbo.Posts WHERE Users.Id IN (Posts.OwnerUserId, Posts.LastEditorUserId) ) ;
SELECT Users.Id FROM dbo.Users WHERE Users.Reputation = 5 AND ( EXISTS (SELECT 1 FROM dbo.Posts WHERE Users.Id = Posts.OwnerUserId) OR EXISTS (SELECT 1 FROM dbo.Posts WHERE Users.Id = Posts.LastEditorUserId) ) ;