एक रनटाइम में एक क्लॉज के लिए एक ज्वाइन को ऑप्टिमाइज़ किया जाता है?


14

जब मैं इस तरह से एक प्रश्न लिखता हूँ ...

select *
from table1 t1
join table2 t2
on t1.id = t2.id

क्या एसक्यूएल ऑप्टिमाइज़र, निश्चित नहीं है कि अगर यह सही शब्द है, तो इसका अनुवाद करें ...

select *
from table1 t1, table2 t2
where t1.id = t2.id

अनिवार्य रूप से, SQL सर्वर में एसक्यूएल लिखने का एक आसान तरीका है जॉइन स्टेटमेंट? या यह वास्तव में रन-टाइम पर उपयोग किया जाता है?

संपादित करें: मैं लगभग हमेशा, और लगभग हमेशा, सिंटैक्स से जुड़ें का उपयोग करेगा। मैं बस उत्सुक हूं कि क्या होता है।


1
क्या आप "लगभग" पर विस्तार से बता सकते हैं? आप पुराने शैली के सिंटैक्स का उपयोग कब और क्यों करेंगे?
हारून बर्ट्रेंड

2
एक किनारे मामले में जहां यह एक फर्क पड़ता है अगर आप एक (बहिष्कृत) जोड़ने GROUP BY ALLमें
मार्टिन स्मिथ

@MartinSmith किसी GROUP BY ALLउद्देश्य पर उपयोग करता है ? :-)
हारून बर्ट्रेंड

@AaronBertrand - मुझे संदेह है! मुझे नहीं लगता कि मैंने कभी किसी को इसका इस्तेमाल करते देखा है।
मार्टिन स्मिथ

जवाबों:


20

वे आंतरिक रूप से एक ही चीज़ के ढह जाते हैं। पूर्व वह है जिसे आपको हमेशा लिखना चाहिए । इससे भी महत्वपूर्ण बात, यह क्यों मायने रखता है? वे निष्पादन योजना और प्रदर्शन के मामले में समान हैं (यह मानते हुए कि आप इसे गड़बड़ नहीं करते हैं, जो आलसी, पुरानी शैली के सिंटैक्स के साथ करना आसान है)।

यहाँ एडवेंचरवर्क्स का उपयोग करते हुए सबूत है कि वहाँ नहीं है CROSS JOINऔर filterचल रहा है।


स्पष्ट सम्मिलित हों:

यहाँ छवि विवरण दर्ज करें


निहित जुड़ाव:

यहाँ छवि विवरण दर्ज करें


देखो, मा! समान योजनाओं, समान परिणाम, कोई क्रॉस जॉइन या फ़िल्टर कहीं भी नहीं देखा जाता है।

(स्पष्टता के लिए, SELECTदोनों मामलों में ऑपरेटर पर चेतावनी एक कार्डिनैलिटी-प्रभावित निहितार्थ है, दोनों मामलों में शामिल होने के साथ कुछ भी नहीं करना है।)


20

कड़ाई से बोलने पर, दो रूपों के बीच क्वेरी ऑप्टिमाइज़र के इनपुट में अंतर होता है:

-- Input tree (ISO-89)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM 
    Production.Product AS p,
    Production.ProductInventory AS inv
WHERE
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

ISO-89 इनपुट ट्री

-- Input tree (ISO-92)
SELECT
    p.Name,
    Total = SUM(inv.Quantity)
FROM Production.Product AS p
JOIN Production.ProductInventory AS inv ON
    inv.ProductID = p.ProductID
GROUP BY
    p.Name
OPTION (RECOMPILE, QUERYTRACEON 8605, QUERYTRACEON 3604);

आईएसओ -92 इनपुट ट्री

जैसा कि आप देख सकते हैं, ON क्लॉज विधेय को आधुनिक वाक्यविन्यास का उपयोग करने के लिए कसकर बाध्य किया गया है। पुराने सिंटैक्स के साथ, एक तार्किक क्रॉस ज्वाइन होता है जिसके बाद एक रिलेशनल सेलेक्ट (एक पंक्ति फ़िल्टर) होता है।

क्वेरी ऑप्टिमाइज़र लगभग हमेशा अनुकूलन के दौरान जुड़ने में संबंधपरक चयन को ध्वस्त कर देता है, जिसका अर्थ है कि दो रूप बहुत समान रूप से समान क्वेरी योजनाओं का उत्पादन करेंगे, लेकिन कोई वास्तविक गारंटी नहीं है।


4

आंतरिक जुड़ने के लिए वे विनिमेय हैं, लेकिन बाहरी जोड़ों के लिए उनके अलग-अलग अर्थ हैं - ऑन मिलान है और जहां साधारण फ़िल्टरिंग है। तो इसका बेहतर ऑन पर जॉय सिंटैक्स मिलान करने के लिए बेहतर है।


4

ठीक है, मैं उत्सुक था इसलिए मैंने एक परीक्षण किया। मुझे निम्नलिखित के लिए वास्तविक निष्पादन योजनाएं मिलीं।

select * 
from sys.database_principals prin, sys.database_permissions perm
WHERE prin.principal_id = perm.grantee_principal_id

तथा

select * 
from sys.database_principals prin
JOIN sys.database_permissions perm
    ON prin.principal_id = perm.grantee_principal_id

मैंने उनकी तुलना वस्तु से की और वे समान थे। तो कम से कम एक बहुत ही सरल उदाहरण के लिए, वे एक ही बात के लिए सामने आए। मैंने आँकड़ों के आईओ और समय की भी जाँच की और वे एक ही चीज़ के काफी करीब थे।

यह कहा जा रहा है, आपको JOINसिंटैक्स का उपयोग करना चाहिए क्योंकि यह पढ़ना आसान है और आप गलतियों को कम करने की संभावना रखते हैं, विशेष रूप से जटिल प्रश्नों में। और जॉइन के लिए *=/ =*सिंटैक्स OUTERपहले ही SQL-Server 2005 के रूप में हटा दिया गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.