2012-03-29 11 views
12

मेरा google-fu और so-fu मुझे यहां विफल कर रहा है, इसलिए मैं भी पूछ सकता हूं।टीएसक्यूएल - टेबल में शामिल होने के लिए उचित आदेश क्या है?

मेरे पास एकाधिक में शामिल होने के साथ कई प्रश्न हैं।

एक प्रश्न के भीतर, मैं एक साथ हेडर/आइटम/विवरण में शामिल हो रहा हूं, साथ ही साथ इन अभिलेखों के लिए जानकारी के विभिन्न बिट्स देख रहा हूं।

शामिल होने पर, मैं चीज़ों को उनके संबंधित तरीके के क्रम में रखने की कोशिश करता हूं। उदा।: मेरे शीर्षलेख में दो लुकअप टेबल हैं, इसलिए मैं अपनी आइटम तालिका में शामिल होने से पहले उन लोगों से जुड़ जाऊंगा।

क्या यह सही है?

लुकअप टेबल से पहले बड़ी टेबल में शामिल होना बेहतर है? या ठीक इसके विपरीत?

क्या मुझे छोटी टेबल में शामिल होने पर loop संकेत का उपयोग करना चाहिए, और merge संकेत ओपनरोसेट में शामिल होने पर संकेत देना चाहिए?

मुझे यकीन है कि उत्तर "यह निर्भर करता है", लेकिन प्रभावी और कुशलता से जुड़ने के लिए कुछ सामान्य दिशानिर्देश बहुत उपयोगी होंगे। धन्यवाद!

+0

ज्यादातर मामलों में आपको शामिल होने के प्रकार (मर्ज/लूप/हैश) निर्दिष्ट करने की आवश्यकता नहीं है। यदि आप ऐसा करते हैं तो शायद अंतर्निहित समस्याएं हैं जिन्हें संकेत बैंड-सहायता में शामिल होने के बजाय हल किया जाना चाहिए। –

+2

जब तक आप बहुत अच्छी तरह से नहीं जानते कि आप क्या कर रहे हैं, और आप क्वेरी निष्पादन योजनाओं को समझते हैं, कभी भी क्वेरी संकेतों का उपयोग न करें। – JotaBe

उत्तर

12

संपादित करें: आपके प्रश्नों (और किर्क वोल की) टिप्पणी के आधार पर, आपको समझना चाहिए कि order of your joins is aesthetic, and does not directly impact the resulting execution plan। क्वेरी ऑप्टिमाइज़र सबसे कुशल क्रम में जॉइन को निष्पादित करेगा, और बिना किसी संकेत के उचित समय के उचित भाग ऑपरेशन का उपयोग करेगा।

जब आपके शामिल होने के सौंदर्यशास्त्र की बात आती है तो यह थोड़ा सा व्यक्तिपरक होता है, लेकिन मैं कहता हूं कि क्वेरी के माध्यम से पढ़ने के दौरान जो भी आदेश तार्किक अर्थ बनाता है, ... यदि आप @HeaderId से शुरू करते हैं, उस तालिका के साथ शुरू, और फिर JOIN बच्चों तालिकाओं के लिए:

FROM 
    Header h 
    JOIN Items i ON h.HeaderId = i.HeaderId 
    JOIN Details d ON i.ItemId = d.ItemId 
WHERE 
    h.HeaderId = @HeaderId 

लेकिन, यदि आप एक @DetailId साथ आपकी क्वेरी शुरू कर दिया, मैं विपरीत क्रम में शामिल हो जाएगा।

FROM 
    Details d 
    JOIN Items i ON d.ItemId = i.ItemId 
    JOIN Header h ON i.HeaderId = h.HeaderId 
WHERE 
    d.DetailId = @DetailId 

हालांकि, यह व्यक्तिपरक और सिर्फ मेरी निजी वरीयता है।

जब आप OUTER JOIN एस शामिल करना शुरू करते हैं तो यह कम व्यक्तिपरक हो जाता है ... RIGHT OUTER JOIN एस से बचने के लिए अपनी क्वेरी को व्यवस्थित करने का प्रयास करें, और इसके बजाय LEFT OUTER JOIN का उपयोग करें।

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

+1

शायद ओपी इस बात से अनजान है कि आदेश में शामिल होना निष्पादन योजना के लिए अप्रासंगिक है और पूरी तरह से सौंदर्यशास्त्र है? –

+0

@ किर्कवॉल यह एक बहुत अच्छा मुद्दा है जिसे मैंने अनदेखा किया ... मैं अपने उत्तर में यह स्पष्ट करूंगा। –

+0

@ किर्क, यही कारण है कि मैं पूछ रहा हूं। आदेश बिल्कुल प्रासंगिक नहीं है? – IronicMuffin

0

आदेश काफी हद तक [1] सौंदर्यशास्त्र है, लेकिन मुझे लगता है कि भ्रम से बचने के लिए टेबल के क्रम और शर्तों दोनों शर्तों के लिए एक सम्मेलन रखना उपयोगी है।

क्वेरी संकेत केवल असाधारण मामलों के लिए हैं, और जब आप उन परिस्थितियों को ढूंढ सकते हैं जहां आपको उनका उपयोग करने की आवश्यकता है (आम तौर पर कम समेकन समस्याओं को कम करने के लिए प्रदर्शन का त्याग करना) आपको हमेशा समस्या को ठीक करने के लिए एक और अधिक मजबूत तरीका खोजने का प्रयास करना चाहिए।

CREATE TABLE A (
    id int IDENTITY PRIMARY KEY, 
    name varchar 
); 

CREATE TABLE B (
    id int IDENTITY PRIMARY KEY, 
    a_id int FOREIGN KEY REFERENCES A (id), 
    name varchar 
); 

SELECT * 
FROM A 
INNER LOOP JOIN B on A.id = B.a_id; 

SELECT * 
FROM B 
INNER LOOP JOIN A on A.id = B.a_id; 

पहले का चयन दो सूचकांक स्कैन करता है, दूसरा एक स्कैन और एक की तलाश करता है:

[1] मैं एक मामले में जहां आदेश फर्क पड़ता है के बारे में पता। संकेतों से बचने के लिए यह एक और अच्छा कारण है।

संबंधित मुद्दे