क्या एक विदेशी कुंजी स्वचालित रूप से एक सूचकांक बनाती है?


389

मुझे बताया गया है कि यदि मैं दो प्रमुख तालिकाएँ बनाता हूँ, तो SQL सर्वर चाइल्ड टेबल में एक इंडेक्स के लिए कुछ बनाएगा। मेरे पास इसे सच मानने का एक कठिन समय है, लेकिन विशेष रूप से इससे संबंधित बहुत कुछ नहीं मिल सकता है।

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


मुझे आपके डीबी लड़के के समान समझ है - कि एफके वास्तव में एक सूचकांक बनाते हैं।
विनी

9
नहीं - एक एफके स्वचालित रूप से एक सूचकांक नहीं बनाता है। यह एक बनाने के लिए समझ में आता है - लेकिन यह SQL सर्वर द्वारा स्वचालित रूप से नहीं किया जाता है।
marc_s

47
यह पूछने के लिए मूर्खतापूर्ण नहीं!
marc_s

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

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

जवाबों:


343

एक विदेशी कुंजी एक बाधा है, दो तालिकाओं के बीच एक संबंध है - जिसका प्रति सूचकांक के साथ कोई लेना-देना नहीं है।

लेकिन यह एक ज्ञात तथ्य है कि यह उन सभी स्तंभों को अनुक्रमित करने के लिए बहुत मायने रखता है जो किसी भी विदेशी कुंजी संबंध का हिस्सा हैं, क्योंकि एफके-रिश्ते के माध्यम से, आपको अक्सर संबंधित तालिका देखने और कुछ पंक्तियों को आधार बनाने की आवश्यकता होगी एकल मान या मानों की श्रेणी।

तो यह एक FK में शामिल किसी भी कॉलम को इंडेक्स करने के लिए अच्छा समझ में आता है, लेकिन प्रति FK एक सूचकांक नहीं है।

Kimberly Tripp का उत्कृष्ट लेख देखें "जब SQL सर्वर ने विदेशी कुंजी कॉलम पर अनुक्रमित करना बंद कर दिया था?"


हां। मैं सिर्फ इस बारे में सकारात्मक हूं कि PostgreSQL एक इंडेक्स बनाता है। मुझे पूरा यकीन है कि MySQL करता है। सूचकांक बनाने से एक टन का अर्थ होता है, लेकिन यह आवश्यक नहीं है। आखिरकार, कुछ क्यों संदर्भ अगर हर बार DB यह देखने के लिए जाता है कि उसे एक टेबलस्कैन करना है?
MBCook

ऊपर उल्लिखित यह लेख भ्रमित करने वाला है क्योंकि SQL सर्वर या कोई अन्य डेटाबेस कभी भी FK पर कोई इंडेक्स नहीं डालता है।
vsingh

7
@vsingh: यह वही है जो लेख को व्यक्त करने की कोशिश करता है - यह एक सामान्य गलत धारणा है कि एफके स्वचालित रूप से एक सूचकांक बनाता है - यह ऐसा नहीं करता है।
marc_s

5
@MBCook नहीं, PostgreSQL करता नहीं (9.2 या किसी पिछले संस्करण में कम से कम) स्वचालित रूप से एक विदेशी कुंजी रिश्ते के साथ परिभाषित के संदर्भित ओर एक सूचकांक बनाने REFERENCES। यह स्वचालित रूप से एक या बाधा के UNIQUEलिए एक सूचकांक बनाता है , और इसके लिए आवश्यक है कि एक सूचकांक एक विदेशी कुंजी संबंध के संदर्भित अंत के लिए मौजूद हो , लेकिन संदर्भित अंत के लिए स्वचालित रूप से कुछ भी नहीं करता है , हालांकि यह अक्सर अपने आप को बनाने के लिए एक अच्छा विचार है। देखें stackoverflow.com/questions/970562/...PRIMARY KEYUNIQUEUNIQUE
क्रेग रिंगर

16
भ्रम हो सकता है क्योंकि MySQL InnoDB दोनों की आवश्यकता होती है और जब आप एक विदेशी कुंजी जोड़ते हैं तो स्वचालित रूप से एक इंडेक्स बनाता है - dev.mysql.com/doc/refman/5.5/en/…
humbads

42

वाह, जवाब सभी नक्शे पर हैं। तो प्रलेखन कहते हैं:

एक प्रमुख कुंजी बाधा सूचकांक के लिए एक उम्मीदवार है क्योंकि:

  • संबंधित तालिकाओं में प्राथमिक कुंजी बाधाओं की जाँच की जाती है और संबंधित तालिकाओं में प्रमुख कुंजी बाधाओं के साथ जाँच की जाती है।

  • विदेशी कुंजी कॉलम का उपयोग अक्सर मापदंड में किया जाता है जब संबंधित तालिका के डेटा को अन्य तालिका में प्राथमिक या अद्वितीय कुंजी कॉलम (ओं) के साथ एक तालिका के FOREIGN कुंजी अवरोध में कॉलम (s) से मेल करके प्रश्नों में जोड़ा जाता है। एक इंडेक्स Microsoft® SQL Server ™ 2000 को विदेशी कुंजी तालिका में संबंधित डेटा को जल्दी से खोजने की अनुमति देता है। हालाँकि, इस सूचकांक को बनाना कोई आवश्यकता नहीं है। दो संबंधित तालिकाओं से डेटा को जोड़ा जा सकता है भले ही कोई प्राथमिक कुंजी या विदेशी कुंजी बाधाओं को तालिकाओं के बीच परिभाषित न किया गया हो, लेकिन दो तालिकाओं के बीच एक विदेशी कुंजी संबंध इंगित करता है कि कुंजी के रूप में उपयोग की जाने वाली क्वेरी में दो तालिकाओं को संयोजित किया जाना है। इसके मापदंड।

तो यह बहुत स्पष्ट लगता है (हालांकि प्रलेखन थोड़ा गड़बड़ है) कि यह वास्तव में एक सूचकांक नहीं बनाता है।


5
वास्तव में - यह एक सूचकांक के लिए एक संकेत है - लेकिन यह स्वचालित रूप से एक के रूप में नहीं बनाया गया है! काफी स्पष्ट रूप से, IMHO :-)
marc_s

4
मैंने पाया कि यह हिस्सा गड़बड़ है: "दो तालिकाओं के बीच एक विदेशी कुंजी संबंध इंगित करता है कि दो तालिकाओं को एक क्वेरी में संयोजित करने के लिए अनुकूलित किया गया है जो कुंजियों को इसके मानदंड के रूप में उपयोग करता है।" यह पढ़ना चाहिए "... दो तालिकाओं को अनुकूलित किया जाना चाहिए ..."
यिशै

18

नहीं, विदेशी कुंजी क्षेत्रों पर कोई अंतर्निहित सूचकांक नहीं है, अन्यथा Microsoft "विदेशी कुंजी पर एक इंडेक्स बनाना अक्सर उपयोगी क्यों होता है " कहता है । प्राथमिक कुंजी - अपने सहयोगी के लिए भेजा करने के लिए तालिका में प्राथमिक कुंजी के साथ चर्चा करते हुए तालिका में विदेशी कुंजी क्षेत्र भ्रमित किया जा सकता है है एक अंतर्निहित सूचकांक पैदा करते हैं।


"एक निहित सूचकांक" क्या है? क्या इसका मतलब यह है कि इसे बनाने के बिना ए बी * वृक्ष है?
स्टेफनी पेज

1
@ स्टेफ़नी पेज: यह एक अभिव्यक्ति है जिसे मैंने इस उत्तर के लिए बनाया है जिसका मतलब है कि एक इंडेक्स जो स्वचालित रूप से बनाया गया है। यदि आप एक प्राथमिक कुंजी घोषित करते हैं, तो SQL सर्वर स्वचालित रूप से इसके लिए बनाता है और अनुक्रमणित करता है। लेकिन ऐसा नहीं है कि आप एक विदेशी कुंजी घोषित करते हैं (कुछ अन्य डीबी सिस्टम करते हैं)।
माइकल बोर्गवर्ड

7

एसक्यूएल सर्वर प्राथमिक कुंजी के लिए सूचकांकों को ऑटो करता है, लेकिन विदेशी कुंजी के लिए नहीं। फॉरेन कीज के लिए इंडेक्स बनाएं। यह शायद ओवरहेड के लायक है।


6

कहते हैं कि आपके पास ऑर्डर नाम की एक बड़ी टेबल है, और ग्राहकों के लिए एक छोटी टेबल है। एक ऑर्डर से एक ग्राहक के लिए एक विदेशी कुंजी है। अब यदि आप किसी ग्राहक को हटाते हैं, तो Sql Server को यह देखना होगा कि कोई अनाथ आदेश नहीं हैं; अगर वहाँ हैं, यह एक त्रुटि उठाता है।

यह देखने के लिए कि क्या कोई आदेश हैं, Sql सर्वर को बड़े ऑर्डर तालिका को खोजना होगा। अब यदि कोई सूचकांक है, तो खोज तेज होगी; अगर वहाँ नहीं है, तो खोज धीमी होगी।

तो इस मामले में, एक इंडेक्स की अनुपस्थिति से धीमी गति से हटाने को समझाया जा सकता है। खासकर अगर Sql Server को इंडेक्स के बिना 15 बड़ी टेबल की खोज करनी होगी।

PS यदि विदेशी कुंजी पर DELETE CASCADE है, तो Sql सर्वर को अभी भी आदेश तालिका खोजना है, लेकिन फिर हटाए गए ग्राहक को संदर्भित करने वाले किसी भी आदेश को हटाने के लिए।


वास्तव में - यही कारण है कि एक FK पर एक इंडेक्स बहुत मायने रखता है (ज्यादातर समय)
marc_s

1
सर्वाधिक समय? लगता है कि यह एक माता-पिता से हटाने के लिए मामला है। यदि अधिकांश समय आप माता-पिता से हटाते हैं, तो मुझे लगता है कि यह सच है।
स्टेफनी पेज

6

विदेशी कुंजियाँ अनुक्रमणिका नहीं बनाती हैं। केवल वैकल्पिक कुंजी बाधाएँ (UNIQUE) और प्राथमिक कुंजी बाधाएँ अनुक्रमणिकाएँ बनाती हैं। यह ओरेकल और एसक्यूएल सर्वर में सच है।


3

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


3

कड़े शब्दों में, विदेशी चाबियों का इंडेक्स से कोई लेना-देना नहीं है, हां। लेकिन, जैसा कि मेरे ऊपर के वक्ताओं ने बताया, यह एफके-लुकअप को गति देने के लिए एक बनाने के लिए समझ में आता है। वास्तव में, MySQL में, यदि आप अपने FK घोषणा में कोई इंडेक्स निर्दिष्ट नहीं करते हैं, तो इंजन (InnoDB) इसे आपके लिए स्वचालित रूप से बनाता है।


3

PostgeSql में आप अपने आप को अनुक्रमित करने के लिए जाँच कर सकते हैं यदि आपने \ d टैबलेन का नाम दिया है

आप देखेंगे कि btree इंडेक्स प्राथमिक कुंजी और अद्वितीय बाधाओं के साथ कॉलम पर स्वचालित रूप से बनाए गए हैं, लेकिन विदेशी कुंजी वाले कॉलम पर नहीं।

मुझे लगता है कि आपके प्रश्न का उत्तर कम से कम पोस्टग्रेज के लिए है।


क्षमा करें, मैंने ध्यान नहीं दिया कि प्रश्न MS SQL सर्वर की चिंता करता है लेकिन उत्तर पोस्ट करने के बाद। यह शायद अभी भी किसी की मदद कर सकता है ...
ग्रेगोर

2

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


मुझे विश्वास नहीं होता है कि यदि आप मैन्युअल रूप से कॉलम को इंडेक्स के भाग के रूप में चिह्नित करते हैं (जैसे कि यदि आप कई सदस्यों पर एक संयुक्त इंडेक्स बना रहे हैं)
रॉलैंड शॉ

0

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

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