कहाँ बनाम पर सूचकांक प्रदर्शन


26

मेरे पास दो टेबल हैं

@T1 TABLE
(
    Id INT,
    Date DATETIME
)

@T2 TABLE
(
    Id INT,
    Date DATETIME
)

इन तालिकाओं पर एक गैर-संकुलित सूचकांक है (Id, Date)

और मैं इन तालिकाओं में शामिल होता हूं

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
WHERE 
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

यह भी लिखा जा सकता है

SELECT *
FROM T1 AS t1
INNER JOIN T2 AS t2
ON 
    t1.Id = t2.Id
    AND
    t1.Date <= GETDATE()
    AND
    t2.Date <= GETDATE()

मेरा प्रश्न यह है कि इन दोनों में से कौन सा प्रश्न बेहतर प्रदर्शन देता है और क्यों? या वे समान हैं?


1
क्या आपके पास वास्तव में एक @ गैर-क्लस्टर इंडेक्स के साथ एक वैरिएबल है जो सभी क्षेत्रों को कवर करता है, और कोई क्लस्टर इंडेक्स नहीं है? या सिर्फ एक सरलीकरण है?
रेमस रूसु

1
यह एक चरम सरलीकरण है
एरिक बर्गस्टेड

जवाबों:


32

प्रदर्शन वही रहेगा। आशावादी व्यक्ति इसे पहचान कर उसी योजना का निर्माण करेगा।

दूसरी ओर मैं नहीं कहूंगा कि वे समान हैं। प्रश्न में पहला रूप कहीं अधिक पठनीय और आम तौर पर अपेक्षित है।

एक उदाहरण के लिए कुछ तालिकाओं का उपयोग करने के बाद, आप देख सकते हैं कि निष्पादन योजना बिल्कुल वैसी ही है, चाहे मैं कोई भी प्रश्न कैसे लिखूं।

आपको अपने स्वयं के तालिकाओं और डेटा सेट के लिए क्वेरी योजनाओं को निर्धारित करने में सक्षम होना चाहिए ताकि आप देख सकें कि आपकी स्थिति में क्या होता है।

SELECT * FROM salestable , custtable 
WHERE salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable 
JOIN  custtable 
ON salestable.custaccount = custtable.accountnum 
AND salestable.dataareaid = custtable.dataareaid

SELECT * FROM salestable JOIN custtable 
ON salestable.custaccount = custtable.accountnum 
WHERE salestable.dataareaid = custtable.dataareaid

इन निष्पादन योजनाओं को देता है

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


मैं मानता हूं, पहला रूप पढ़ना आसान है, और मुझे इस तरह राहत मिली है कि वे समान हैं। मैं भविष्य में केवल इस फॉर्म का उपयोग करूंगा।
एरिक बर्गस्टेड

@ErikBergstedt मैंने अपना उत्तर संपादित किया, जब आप निष्पादन योजनाओं को देखते हैं, तो आपको अपने डेटासेट और तालिका संरचना को आसानी से सत्यापित करने में सक्षम होना चाहिए
टॉम वी - टीम मोनिका

हाँ, मैंने किया। धन्यवाद। मुझे केवल एक 2 राय की तलाश थी क्योंकि मुझे कोई मौजूदा उत्तर नहीं मिला।
एरिक बर्गस्टेड

नोट: यदि यह एक है तो वे केवल समान हैं INNER JOIN। यदि आप एक फेंक देते OUTER JOINहैं तो वे निश्चित रूप से समान नहीं होते हैं।
केनेथ फिशर

22

वे शब्दार्थ समान हैं और आशावादी को इस तथ्य को पहचानने और समान योजनाएँ बनाने में कोई परेशानी नहीं होनी चाहिए।

मैं दोनों तालिकाओं को संदर्भित करने वाली शर्तों को ONऔर केवल एक तालिका को संदर्भित करने वाली शर्तों को रखता हूं WHERE

के लिए OUTER JOINSस्थिति आगे बढ़ तथापि अर्थ विज्ञान को प्रभावित कर सकते हैं।


7

साधारण मामलों में, यह समान होगा। हालाँकि, मैंने कई जटिल प्रश्नों को देखा है, जिनमें कई जोड़ियाँ अलग-अलग योजनाएँ हैं। हाल ही में मैं जिस पर काम कर रहा था, वह एक ऐसी तालिका के साथ शुरू हुई जिसमें 6 मिलियन पंक्तियों के करीब 20 अलग-अलग तालिकाओं में शामिल हुए। केवल इस तालिका में पहली बार शामिल होने वाली एक आंतरिक जोड़ी थी, अन्य सभी बाहरी जोड़ छोड़ दिए गए थे। जहां क्लॉज को फिल्टर किया गया था, उसे इस तरह से फिल्टर किया गया था:

WHERE table1.begindate >= @startdate AND table1.enddate < @enddate 

इस फ़िल्टर का उपयोग बाद में पहले की बजाय योजना में किया गया था। जब मैंने इन स्थितियों को पहले आंतरिक में शामिल किया, तो योजना में नाटकीय रूप से बदलाव आया क्योंकि परिणाम सेट को सीमित करने के लिए फ़िल्टर को जल्दी से लागू किया गया और मेरा सीपीयू और बीता हुआ समय लगभग 310% कम हो गया। इसलिए, कई SQL सर्वर प्रश्नों के साथ, यह निर्भर करता है।


2
क्या आप अधिक विवरण जोड़ सकते हैं - शायद निष्पादन योजना के स्क्रीनशॉट - आपके उत्तर अन्य सभी के विपरीत प्रतीत होते हैं?
केनी एविट

2
क्या योजना ने एक आशावादी समयबाह्य दिखाया?
मार्टिन स्मिथ

CPU लोड संभवतः 100% से अधिक कैसे कम हो सकता है?
माइकल ग्रीन

2

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

ऑप्टिमाइज़र यह तय कर सकता है कि बैच का यह हिस्सा पर्याप्त समय बिताने के लायक नहीं है, ताकि यह सबसे अच्छी योजना के साथ आ सके। सामान्य तौर पर आपको बेहतर प्रदर्शन मिलेगा यदि आप ऐसी शर्तें रखते हैं जो डेटा की मात्रा को कम करती हैं, तो क्वेरी को WHERE क्लॉज़ के बजाय ON क्लॉज़ में काम करना होगा (यदि संभव हो तो, क्योंकि बाहरी जुड़ाव के साथ ऐसा करने से कार्टेशियन उत्पाद हो जाएगा ।)

कभी-कभार SQL डेवलपर के लिए WHERE क्लॉज़ में फ़िल्टर करना थोड़ा आसान होता है, लेकिन मैंने कुछ बड़े टेबलों पर काम किया है जहाँ ऑन क्लॉज़ में फ़िल्टर होने से रन टाइम बंद हो जाता है।

इसलिए यदि खंड में उन पंक्तियों की संख्या को काफी कम करने की क्षमता है, जो क्वेरी पढ़ेगी, तो मैं हमेशा ऑप्टिमाइज़र को बेहतर योजना चुनने में मदद करने के लिए इसे ON खंड में रखूँगा।


1

सामान्य परिस्थितियों में, फ़िल्टर की शर्तों को WHERE या JOIN क्लॉस में निर्दिष्ट किया जा सकता है। जब तक OUTER JOIN पूर्वता प्रभावित नहीं हो सकती (जब तक कि नीचे दी गई है) या यदि फ़िल्टर तालिका के लिए बहुत विशिष्ट है (जैसे TYPE = 12 तालिका में पंक्तियों का एक विशिष्ट सबसेट निर्दिष्ट करने के लिए), तो मैं WHERE के तहत फ़िल्टर्स रखना पसंद करता हूँ।

दूसरी ओर ON और WHERE क्लॉज़ दोनों का उपयोग जुड़ने की स्थिति (फ़िल्टर की शर्तों के विपरीत) को निर्दिष्ट करने के लिए किया जा सकता है। जब तक आप केवल INNER जॉइन का उपयोग कर रहे हैं, तब भी यह कोई फर्क नहीं पड़ेगा जो आप सामान्य परिस्थितियों में उपयोग करते हैं।

यदि आप OUTER जॉइन का उपयोग कर रहे हैं, हालांकि, यह बहुत अंतर कर सकता है। यदि, उदाहरण के लिए, आप दो तालिकाओं (t1 और t2) के बीच एक OUTER JOIN निर्दिष्ट करते हैं, लेकिन तब, WHERE क्लॉज में, तालिकाओं के बीच एक eqijoin संबंध निर्दिष्ट करें (जैसे t1.col = t2.col), आपके पास बस OUTER को INNER जॉइन में परिवर्तित करें! इसका कारण यह है कि WH समान का उपयोग करने के लिए इस्तेमाल किया जा सकता है (या हो सकता है कि OUTER भी शामिल हो, संस्करण पर निर्भर करते हुए, एक खंड का उपयोग किए बिना, * * वाक्यविन्यास) का उपयोग करते हुए, और जब WHER तालिकाओं के बीच एक आंतरिक समरूपता का संकेत देता है, तो यह एक OUTER पर निर्भर करता है जोइन (यदि मौजूद है)।

मूल प्रश्न फ़िल्टर के बारे में था, जिसमें अक्सर शामिल होने का प्रकार एक मुद्दा नहीं होना चाहिए, लेकिन एक जुड़ाव भी फ़िल्टर के रूप में कार्य कर सकता है और उन स्थितियों में शामिल होने की स्थिति का स्थान निश्चित रूप से मायने रख सकता है।


-1

INNER JOINs के साथ, यह एक स्टाइल इश्यू है।

हालाँकि, यह OUTER JOINs के साथ कहीं अधिक दिलचस्प हो जाता है। आपको OUTER JOINs और शर्तों के साथ क्वेरीज़ के बीच अंतर का पता लगाना चाहिए और ON दोनों क्लॉज़ और WHERE क्लॉज़। परिणाम-सेट हमेशा समान नहीं होता है। उदाहरण के लिए,

OUTER JOIN dbo.x ON a.ID = x.ID ... WHERE x.SomeField IS NOT NULL

बराबर

INNER JOIN dbo.x ON a.ID = x.ID AND x.SomeField IS NOT NULL

8
यदि परिणाम अलग है (जो कि निश्चित रूप से है), तो प्रदर्शन की तुलना करने का क्या मतलब है?
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.