2010-07-01 16 views
9

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

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car 
INNER JOIN Car_Part ON Car_Part.Car_Id = Car.Car_Id 
WHERE Car_Part.Part_Id = @part_to_look_for 
GROUP BY Car.Col1, Car.Col2, Car.Col3 

या मैं अब इस

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car 
WHERE Car.Car_Id IN (SELECT Car_Id FROM Car_Part WHERE Part_Id = @part_to_look_for) 

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

मुझे यह इंगित करना चाहिए कि हम SQL Server 2008 पर हैं। मुझे यह भी कहना चाहिए कि वास्तव में मैं भाग आईडी, भाग प्रकार और संभवतः अन्य चीजों के आधार पर भी चयन करना चाहता हूं। तो, क्वेरी मैं वास्तव में क्या करना चाहते हैं इस तरह दिखता है:

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car 
INNER JOIN Car_Part ON Car_Part.Car_Id = Car.Car_Id 
INNER JOIN Part ON Part.Part_Id = Car_Part.Part_Id 
WHERE (@part_Id IS NULL OR Car_Part.Part_Id = @part_Id) 
AND (@part_type IS NULL OR Part.Part_Type = @part_type) 
GROUP BY Car.Col1, Car.Col2, Car.Col3 

या ...

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car 
WHERE (@part_Id IS NULL OR Car.Car_Id IN (
    SELECT Car_Id 
    FROM Car_Part 
    WHERE Part_Id = @part_Id)) 
AND (@part_type IS NULL OR Car.Car_Id IN (
    SELECT Car_Id 
    FROM Car_Part 
    INNER JOIN Part ON Part.Part_Id = Car_Part.Part_Id 
    WHERE Part.Part_Type = @part_type)) 
+2

तुम दोनों को चलाने की है? क्वेरी योजनाओं को देखा? इसे बेंचमार्क किया? – Oded

+1

मुझे डेटा का एक भार उत्पन्न करना होगा, इसलिए मैं अगले सप्ताह तक इसके लिए गोल नहीं करूंगा। और जब मैंने एक जवाब के लिए गुगल किया तो मुझे कोई नहीं मिला, इसलिए किसी और के लिए ऑनलाइन प्रश्न पोस्ट करना उचित है जो शायद देख रहा हो। – d4nt

+0

समूह श्रम गहन है, औसत, रकम इत्यादि जैसी चीजों की गणना करने के लिए प्रयुक्त होता है। आप डुप्लिकेट को खत्म करने के लिए इसका उपयोग कर रहे हैं। समूह के बिना DISTINCT का प्रयास करें ... – Alocyte

उत्तर

3

मेरे पास समान डेटा है इसलिए मैंने क्वेरी की दोनों शैलियों के लिए निष्पादन योजना की जांच की। मेरे आश्चर्य के लिए, कॉलम इन सबक्वायरी (सीआईएस) ने आंतरिक भागीदारी (आईजे) क्वेरी की तुलना में 25% कम I/O लागत के साथ निष्पादन योजना बनाई। सीआईएस निष्पादन योजना में मुझे मध्यवर्ती तालिका (कारपार्ट) के इंटरमीडिएट के इंडेक्स स्कैन के विरुद्ध 2 सूचकांक स्कैन मिलते हैं और आईजे में अपेक्षाकृत अधिक महंगा हैश शामिल होते हैं। मेरी अनुक्रमणिका स्वस्थ लेकिन गैर-क्लस्टर हैं इसलिए इसका कारण यह है कि इंडेक्स स्कैन उन्हें क्लस्टर करके थोड़ा तेज बना सकते हैं। मुझे संदेह है कि यह हैश जॉइन की लागत को प्रभावित करेगा जो आईजे क्वेरी में अधिक महंगा कदम है।

जैसा कि दूसरों ने इंगित किया है, यह आपके डेटा पर निर्भर करता है। यदि आप इन 3 टेबलों में कई गीगाबाइट्स के साथ काम कर रहे हैं तो दूर ट्यून करें। यदि आपकी पंक्तियों को सैकड़ों या हजारों में गिना जाता है तो आप बहुत छोटे प्रदर्शन लाभ पर बाल विभाजित कर सकते हैं। मैं कहूंगा कि आईजे क्वेरी बहुत अधिक पठनीय है, जब तक कि यह काफी अच्छा हो, तब तक कोई भी भविष्य डेवलपर जो आपके कोड को एक पक्ष को छूता है और उन्हें पढ़ने के लिए कुछ आसान देता है। मेरी टेबल में पंक्ति गणना 188877, 283912, 13054 है और दोनों प्रश्नों को कम समय में लौटाया गया है जो इसे कॉफी में ले जाता है।

छोटी पोस्टस्क्रिप्ट: चूंकि आप किसी भी संख्यात्मक मानों को एकत्र नहीं कर रहे हैं, ऐसा लगता है कि आप अलग-अलग चयन करना चाहते हैं। जब तक कि आप वास्तव में समूह के साथ कुछ करने जा रहे हैं, अंत में समूह के बजाए चुनिंदा विशिष्ट के साथ अपना इरादा देखना आसान है।आईओ लागत एक जैसी है लेकिन कोई आपके इरादे को बेहतर IMHO इंगित करता है।

4

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

महत्वपूर्ण बातें शामिल हैं:
- उत्पादन स्तर मात्रा में डेटा पर परीक्षण
- परीक्षण काफी & लगातार (स्पष्ट कैश: http://www.adathedev.co.uk/2010/02/would-you-like-sql-cache-with-that.html)
- कार्य योजना लागू करके

आप या तो मॉनिटर एसक्यूएल प्रोफाइलर का उपयोग कर सकता है की जाँच और एसएसएमएस में आउटपुट आंकड़ों के लिए अवधि/पढ़/लिखने/सीपीयू, या SET STATISTICS IO ON; SET STATISTICS TIME ON; की जांच करें। फिर प्रत्येक क्वेरी के आंकड़ों की तुलना करें।

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

2
एसक्यूएल सर्वर 2008 के साथ

मैं In उम्मीद तेज होने के लिए के रूप में यह इस के बराबर है जाएगा।

SELECT Car.Col1, Car.Col2, Car.Col3 
FROM Car 
WHERE EXISTS(SELECT * FROM Car_Part 
      WHERE Car_Part.Car_Id = Car.Car_Id 
      AND Car_Part.Part_Id = @part_to_look_for 
) 

यानी इसे केवल उस पंक्ति के अस्तित्व की जांच करनी है जिसमें शामिल नहीं है और डुप्लिकेट हटा दें। यह discussed here है।

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