क्या विदेशी कुंजी क्वेरी प्रदर्शन में सुधार करती है?


149

मान लीजिए कि मेरे पास 2 टेबल, उत्पाद और उत्पाद श्रेणी हैं। दोनों तालिकाओं का कैटिगरी पर संबंध है। और यह क्वेरी है।

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category
FROM Products p
INNER JOIN ProductCategories c ON p.CategoryId = c.CategoryId
WHERE c.CategoryId = 1;

जब मैं निष्पादन योजना बनाता हूं, तालिका ProductCategories क्लस्टर इंडेक्स की तलाश करती है, जो उम्मीद के मुताबिक है। लेकिन तालिका उत्पादों के लिए, यह क्लस्टर इंडेक्स स्कैन करता है, जिससे मुझे संदेह होता है। FK क्वेरी प्रदर्शन को बेहतर बनाने में मदद क्यों नहीं करता है?

इसलिए मुझे Products.CategoryId पर इंडेक्स बनाना होगा। जब मैं फिर से निष्पादन योजना बनाता हूं, तो दोनों तालिकाएं सूचकांक की तलाश करती हैं। और अनुमानित सबट्री लागत बहुत कम हो गई है।

मेरे प्रश्न हैं:

  1. एफके के साथ संबंध बाधा पर मदद करता है, क्या इसकी कोई अन्य उपयोगिता है? क्या यह क्वेरी प्रदर्शन में सुधार करता है?

  2. क्या मुझे सभी तालिकाओं में सभी FK कॉलम (पसंद किए गए Products.CategoryId) पर सूचकांक बनाना चाहिए?

जवाबों:


186

विदेशी कुंजी एक संदर्भात्मक अखंडता उपकरण है, न कि प्रदर्शन उपकरण। कम से कम SQL सर्वर में, FK का निर्माण एक संबद्ध इंडेक्स नहीं बनाता है, और आपको बार-बार सुधार करने के लिए सभी FK फ़ील्ड पर इंडेक्स बनाना चाहिए।


40
अच्छे मॉडल (आम तौर पर) बेहतर प्रदर्शन करते हैं।
केनी एविट

10
"विदेशी कुंजी एक संबंधपरक अखंडता उपकरण है" - कृपया देखभाल के साथ 'संबंधपरक' शब्द का उपयोग करें। विदेशी कुंजी एक डेटाबेस अवधारणा है, जो एक संदर्भात्मक अखंडता बाधा के लिए एक छोटा हाथ है। वे संबंधपरक मॉडल का हिस्सा नहीं हैं। मुझे लगता है कि आपने एक टाइपो बनाया है।
onedaywhen

7
@ केनी अक्सर हाँ, लेकिन कभी-कभी एक बेहतर मॉडल की कीमत अधिक होती है। बिंदु में मामला: विदेशी चाबियाँ अधिक प्रसंस्करण का कारण बनती हैं, कम नहीं।
हंस

8
विदेशी कुंजी कर कम से कम MySQL में प्रदर्शन में सुधार,। इसके अलावा, आप सही हैं, एक एफके का निर्माण एक सूचकांक नहीं बनाता है; FK के निर्माण के लिए एक सूचकांक की आवश्यकता होती है
Félix Gagnon-Grenier

15
यह उत्तर बहुत ही बेकार है क्योंकि यह प्रश्न का उत्तर नहीं देता है। यह जानना बहुत अच्छा है कि विदेशी कुंजियों का प्रदर्शन पर (सकारात्मक) प्रभाव होने का इरादा नहीं है , लेकिन सवाल वास्तविकता से संबंधित था, इरादे नहीं।
जॉन

58

विदेशी कुंजी प्रदर्शन में सुधार (और चोट) कर सकती हैं

  1. जैसा कि यहाँ कहा गया है: विदेशी कुंजियाँ प्रदर्शन को बढ़ाती हैं

  2. लुकअप को कम करने के लिए आपको हमेशा FK कॉलम पर इंडेक्स बनाना चाहिए। SQL सर्वर स्वचालित रूप से ऐसा नहीं करता है।

संपादित करें

जैसा कि लिंक अब मृत हो गया है (ध्यान देने योग्य के लिए क्रिस के लिए कुदोस) , निम्नलिखित से पता चलता है कि क्यों विदेशी चाबियाँ बेहतर प्रदर्शन (और चोट) कर सकती हैं।

क्या विदेशी कुंजी प्रदर्शन में सुधार कर सकती है

विदेशी कुंजी बाधा डेटा पढ़ने के समय प्रदर्शन में सुधार करती है, लेकिन साथ ही यह डेटा सम्मिलित / संशोधित / हटाने के समय प्रदर्शन को धीमा कर देती है।

क्वेरी पढ़ने के मामले में, ऑप्टिमाइज़र अधिक कुशल क्वेरी प्लान बनाने के लिए विदेशी कुंजी बाधाओं का उपयोग कर सकता है क्योंकि विदेशी कुंजी बाधाएं घोषित नियम हैं। इसमें आमतौर पर क्वेरी प्लान के कुछ हिस्से को छोड़ दिया जाता है क्योंकि उदाहरण के लिए ऑप्टिमाइज़र यह देख सकता है कि विदेशी कुंजी बाधा के कारण, योजना के उस विशेष भाग को निष्पादित करना अनावश्यक है।


3
यहाँ एक लिंक भी होता है विवरण तरीकों से वे प्रदर्शन में कमी कर सकते हैं devx.com/getHelpOn/10MinuteSolution/16595/0/page/2
cmsjr

3
यह समझ में आता है, लेकिन आप केवल एक बड़े पैमाने पर हटाने के बयान के साथ इसमें भाग लेंगे। शायद निष्कर्ष यह होना चाहिए कि OLAP वातावरण में, गैर-अनुक्रमित FK के प्रदर्शन में सुधार होगा जबकि OLTP वातावरण में, यह प्रदर्शन को नीचा दिखाएगा।
लेवेन कीर्सेमेकर्स

1
इस उत्तर में लिंक मृत है। यह दुर्भाग्यपूर्ण है क्योंकि FKs के प्रदर्शन में सुधार के लिए यह एकमात्र तर्क है।
क्रिस मोसचिनी

1
@ क्रिसमोसचिनी - मैंने अब तक आपकी टिप्पणी पर ध्यान नहीं दिया। जैसा कि आपने उल्लेख किया है, लिंक मृत है, लेकिन इसका उल्लेख नए लिंक (विवरण सहित) में मैंने पोस्ट किया है।
लेवेन केर्सेमेकर्स

2
जीत के लिए Wayback मशीन लिंक ! लेख यहां SQLMag.com पर भी पाया जा सकता है
जॉन आइस्ब्रेनर

15

डेटाबेस की अखंडता सुनिश्चित करने के लिए एक विदेशी कुंजी एक डीबीएमएस अवधारणा है।

किसी भी प्रदर्शन निहितार्थ / सुधार डेटाबेस प्रौद्योगिकी के उपयोग के लिए विशिष्ट होंगे और एक विदेशी कुंजी के उद्देश्य के लिए माध्यमिक हैं।

यह सुनिश्चित करने के लिए SQL सर्वर में अच्छा अभ्यास है कि सभी विदेशी कुंजियों में कम से कम उन पर एक गैर-संकुल सूचकांक है।

मुझे उम्मीद है कि यह आपके लिए चीजों को साफ कर देगा लेकिन कृपया अधिक जानकारी के लिए अनुरोध करने के लिए स्वतंत्र महसूस करें।


9
@ केनी इविट यदि आपके पास अखंडता नहीं है, तो आपका डेटा बेकार है। मुझे लगता है कि बहुत आसानी से बेचता है।
HLGEM

@HLGEM एक समय में 404 त्रुटि प्राप्त करना अभी भी काफी सहनीय है। सस्ते संसाधनों और कम जटिल प्रणालियों का उपयोग करके बदले में असाधारण थ्रूपुट, अब बहुत आसानी से बिकता है। आपको कैप प्रमेय में रुचि हो सकती है
डैनियल डायनीज

8
@ डैनियल डनीज़, डेटा अखंडता 404 त्रुटि प्राप्त करने के बारे में नहीं है। यह प्रयोग करने योग्य डेटा होने के बारे में है। यह डेवलपर्स की अक्षमता के कारण रिपोर्ट के लिए आदेश और वित्तीय डेटा नहीं खोने के बारे में है। विदेशी कुंजियों का उपयोग नहीं करने के लिए कोई अतिरिक्त नहीं है।
HLGEM

2
मैं HLGEM से सहमत हूं। अपने कोड को अखंडता को संभालने देना हमेशा एक अच्छा विचार नहीं है। डेटा का उपयोग अक्सर निर्णय लेने के लिए किया जाता है, लेकिन यदि डेटा दूषित है, तो निर्णय सटीक नहीं होगा।
लेप

1
"विदेशी कुंजी एक संबंधपरक अखंडता उपकरण है" - कृपया देखभाल के साथ 'संबंधपरक' शब्द का उपयोग करें। विदेशी कुंजी एक डेटाबेस अवधारणा है, जो एक संदर्भात्मक अखंडता बाधा के लिए एक छोटा हाथ है। वे संबंधपरक मॉडल का हिस्सा नहीं हैं। मुझे लगता है कि आपने एक टाइपो बनाया है।
onedaywhen

4

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


3

किसी क्वेरी को अधिक कुशल बनाने में सहायता के लिए आप इसका उपयोग कर सकते हैं। यह आपको SQL सर्वर में क्वेरीज़ को रिस्ट्रक्चर करने की अनुमति देता है एक आंतरिक जॉइन के बजाय एक बाहरी जॉइन का उपयोग करने के लिए जो कॉलम में एक अशक्त होने की जाँच करने के लिए SQL सर्वरों की नग्नता को हटा देता है। आपको उस क्वालीफायर को लगाने की आवश्यकता नहीं है क्योंकि विदेशी कुंजी संबंध पहले से ही आपके लिए है।

तो यह:

    select p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
from Products p inner join ProductCategories c on p.CategoryId = c.CategoryIdwhere c.CategoryId = 1;

यह बन जाता है:

SELECT p.ProductId, p.Name, c.CategoryId, c.Name AS Category 
FROM ProductCategories c 
LEFT OUTER JOIN Products P ON
c.CategoryId = p.CategoryId 
WHERE c.CategoryId = 1;

यह आवश्यक रूप से छोटे प्रश्नों में एक बड़ा प्रदर्शन नहीं करेगा, लेकिन जब टेबल बड़े हो जाते हैं तो यह अधिक कुशल हो सकता है।


3
न केवल बाहरी जुड़ाव आंतरिक जोड़ की तुलना में कम कुशल होते हैं ( stackoverflow.com/a/2726683/155892 ), अब आपके प्रश्न भ्रामक हैं: आप डेटाबेस पर भरोसा करते हुए अपने बाहरी जोड़ों को आंतरिक रूप से चालू करते हैं (प्रदर्शन को बहाल करते हुए) केवल स्पष्ट रूप से करने के बजाय
मार्क सोउल

2

MySQL 5.7 के लिए, यह निश्चित रूप से प्रश्नों को गति दे सकता है जिसमें आश्चर्यजनक रूप से कई जोड़ शामिल हैं!

मैंने अपनी क्वेरी को समझने के लिए 'व्याख्या' का उपयोग किया और पाया कि मैं 4-5 तालिकाओं में शामिल हो रहा था - जहाँ कोई भी कुंजी का उपयोग नहीं किया जाता था। मैंने इन तालिकाओं में एक विदेशी कुंजी को जोड़ने के अलावा कुछ नहीं किया और नतीजा लोडटाइम में 90% की कमी हुई। जो क्वेरीज़> 5s अब 500ms या उससे कम लेती हैं।

यह एक सुधार है!

और, जैसा कि दूसरों ने उल्लेख किया है, आपको संबंधपरक अखंडता सुनिश्चित करने का अतिरिक्त बोनस मिलता है।

इसके अलावा, संदर्भात्मक अखंडता सुनिश्चित करने के साथ-साथ इसके स्वयं के प्रदर्शन लाभ भी हैं। यह सुनिश्चित करने का दूसरा क्रम प्रभाव है कि विदेशी तालिकाओं वाले टेबल विदेशी तालिका के साथ 'अप टू डेट' हैं। मान लें कि आपके पास एक उपयोगकर्ता तालिका और एक टिप्पणी तालिका है, और आप टिप्पणी तालिका पर कुछ आँकड़े कर रहे हैं। संभवतः यदि आप उपयोगकर्ता को मुश्किल से हटाते हैं, तो आप उनकी टिप्पणियाँ अब नहीं चाहते हैं।


क्या टेबल में आपके द्वारा जोड़े जाने से पहले विदेशी कुंजी बनाने के लिए आवश्यक अनुक्रमित थे?
जॉर्ज

1

तालिका में एक विदेशी कुंजी जोड़ने से प्रदर्शन में सुधार नहीं होगा, बस यह कहते हुए कि यदि आप किसी ProductCategories तालिका डेटाबेस में कोई रिकॉर्ड सम्मिलित कर रहे हैं, तो उस विदेशी कुंजी कॉलम को खोजने का प्रयास करेंगे जिसका मान किसी उत्पाद तालिका के प्राथमिक कुंजी मान में मौजूद है, यह देखो, हर बार जब आप ProductCategories तालिका में एक नई प्रविष्टि जोड़ते हैं, तो ऑपरेशन आपके डेटाबेस पर हो जाता है। तो एक विदेशी कुंजी जोड़ने से आपके डेटाबेस के प्रदर्शन में सुधार नहीं होगा, लेकिन यह आपके डेटाबेस की अखंडता के बारे में ध्यान रखेगा। यदि आप अपने प्रोग्राम में डेटाबेस में मौजूद रिकॉर्ड को चेक करने के लिए कई प्रश्नों को चलाने के बजाय विदेशी कुंजी का उपयोग करके अखंडता की जांच कर रहे हैं, तो यह आपके db के प्रदर्शन में सुधार करेगा।


0

मुझे SQL सर्वर के बारे में ज्यादा जानकारी नहीं है, लेकिन Oracle के मामले में, एक विदेशी कुंजी कॉलम होने से डेटा-लोडिंग का प्रदर्शन कम हो जाता है। ऐसा इसलिए है क्योंकि डेटाबेस को प्रत्येक सम्मिलित के लिए डेटा अखंडता की जांच करने की आवश्यकता है। और हां, जैसा कि पहले ही उल्लेख किया गया है, विदेशी कुंजी कॉलम पर एक सूचकांक होना एक अच्छा अभ्यास है।


0

SQL सर्वर 2008 के रूप में विदेशी कुंजी क्वेरी को ऑप्टिमाइज़ करने के लिए डेटाबेस इंजन को चुनने के तरीके को प्रभावित करके प्रदर्शन को प्रभावित कर सकता है। निम्नलिखित लेख में स्टार से जुड़ने के संदर्भ देखें: https://technet.microsoft.com/en-us/library/2008.04.dwperformance.aspx

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