यदि आप 2 निष्पादन योजनाओं को देखते हैं, तो क्या एक आसान उत्तर है जो बेहतर है? मैंने जानबूझकर अनुक्रमणिका नहीं बनाई, इसलिए यह देखना आसान है कि क्या हो रहा है।
दूसरी योजना की अनुमानित लागत कम है, इसलिए उस सीमित अर्थ में यह 'बेहतर' है।
डेटा सेट इतने छोटे हैं कि ऑप्टिमाइज़र ने विकल्प देखने में ज्यादा समय नहीं लगाया। क्वेरी का पहला रूप हैश जॉइन का उपयोग करके एक योजना खोजने के लिए होता है और एक टेबल स्पूल पर जल्दी होता है। उस योजना की अनुमानित लागत इतनी कम है कि ऑप्टिमाइज़र कुछ भी बेहतर देखने की जहमत नहीं उठाता है।
क्वेरी का दूसरा रूप खोज प्रक्रिया में केवल नेस्टेड लूप्स बाहरी जोड़ से एक योजना खोजने के लिए होता है, और फिर से अनुकूलक यह तय करता है कि योजना काफी अच्छी है। ऐसा होता है कि यह योजना सस्ती होने का अनुमान है।
कहा कि (जैसा कि प्रश्न टिप्पणियों में उल्लेख किया गया है) दो प्रश्न शब्दार्थ समान नहीं हैं। यह आपके लिए महत्वपूर्ण नहीं हो सकता है यदि आप यह गारंटी दे सकते हैं कि परिणाम आपके डेटाबेस के सभी संभावित भविष्य के राज्यों के लिए हमेशा समान रहेंगे, लेकिन आशावादी उस धारणा को नहीं बना सकता है। यह केवल सभी परिस्थितियों में SQL द्वारा निर्दिष्ट समान परिणाम का उत्पादन करने की गारंटी देने वाली योजनाओं का निर्माण करता है।
मैंने महसूस किया है कि नेस्टेड सिंटैक्स क्वेरी के व्यवहार को भी संशोधित करता है।
'नेस्टेड सिंटैक्स' पूरे एएनएसआई के सिंटैक्स विनिर्देश में शामिल होने का सिर्फ एक पहलू है। अधिक जटिल शामिल होने के पैटर्न के लिए पूर्ण तार्किक विनिर्देश को सक्षम करने के लिए, विनिर्देश (वैकल्पिक) कोष्ठक, और FROM
खंड उप-वर्ग की अनुमति देता है ।
कोष्ठक का उपयोग करते हुए उसी ANSI सिंटैक्स का उपयोग करके क्वेरी लिखी जा सकती है :
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN
(
dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) ON M.ModelID = A.ModelID;
यह प्रपत्र स्पष्ट रूप से दर्शाता है कि तार्किक आवश्यकता को आंतरिक जुड़ने Autos
के परिणाम से छोड़ना Manufacturers
है Models
। वैकल्पिक कोष्ठकों को स्वीकार करने से आपको 'नेस्टेड' नाम का फॉर्म मिलता है:
SELECT
A.*,
M.*,
N.*
FROM dbo.Autos AS A
LEFT JOIN dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
ON M.ModelID = A.ModelID;
यह एक अलग वाक्यविन्यास नहीं है - यह केवल वैकल्पिक कोष्ठकों को छोड़ रहा है और थोड़ा सुधार कर रहा है।
जैसा कि मार्टिन ने उल्लेख किया है, इस मामले में आंतरिक जुड़ावों का उपयोग करके तार्किक आवश्यकता को व्यक्त करना संभव है, इसके बाद एक सही बाहरी जुड़ाव भी शामिल है:
SELECT
A.*,
M.*,
N.*
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
RIGHT JOIN dbo.Autos AS A
ON A.ModelID = M.ModelID;
उपरोक्त सभी तीन क्वेरी फॉर्म एक ही ANSI सिंटैक्स में शामिल होते हैं। सभी तीन भी प्रदान की गई डेटा सेट के साथ एक ही भौतिक निष्पादन योजना का उत्पादन करते हैं:
जैसा कि मैंने आपके पिछले प्रश्न के उत्तर में उल्लेख किया है, ऐसे प्रश्न जो बिल्कुल तार्किक आवश्यकता को व्यक्त करते हैं, हमेशा एक ही निष्पादन योजना नहीं बनाएंगे। आप किस तार्किक क्वेरी फॉर्म का उपयोग करना पसंद करते हैं, यह काफी हद तक शैली का सवाल है। सामान्य रूप से एक विशेष शैली और 'बेहतर' क्वेरी योजनाओं के बीच कोई संबंध नहीं है। मैं आमतौर पर किसी विशेष योजना को प्राप्त करने के लिए एक क्वेरी को फिर से लिखने के खिलाफ सलाह दूंगा अगर नई क्वेरी वास्तव में तार्किक रूप से मूल के समान नहीं है।
SQL मानक FROM
क्लॉज़ सबक्वेरीज़ की अनुमति देता है , इसलिए समान क्वेरी विनिर्देश लिखने का एक और तरीका है:
SELECT *
FROM dbo.Autos AS A
LEFT JOIN
(
SELECT
N.ManufacturerID,
ManufacturerName = N.Name,
M.ModelID,
ModelName = M.Name
FROM dbo.Manufacturers AS N
JOIN dbo.Models AS M
ON M.ManufacturerID = N.ManufacturerID
) AS R1
ON R1.ModelID = A.ModelID;
पारंपरिक सिंटैक्स का उपयोग करते हुए, हमें 'मैन्युफैक्चरर्स' को 'ज्वाइन' में बाहरी रूप से शामिल करना होता है, जैसे ... लेकिन इससे क्वेरी प्लान बदल जाता है।
यह शायद क्वेरी का अर्थ बदल देता है, जिस स्थिति में यह तकनीकी रूप से एक वैध विकल्प नहीं है (लेकिन अपने प्रश्न पर ypercube की टिप्पणी देखें )।
ANSI ज्वाइन सिंटैक्स में (वैकल्पिक) कोष्ठक इस तरह से अधिक जटिल जुड़ाव आवश्यकताओं के लिए ठीक हैं, इसलिए आपको जहां आवश्यक हो, वहां उनका उपयोग करने से डरना नहीं चाहिए।