Czy klucz obcy automatycznie tworzy indeks?

MS SQL Server 2000

Głupio mi zadawać to pytanie, ale powiedziano mi, że jeśli użyję klucza do dwóch tabel, to SQL Server stworzy coś podobnego do indeksu w tabeli podrzędnej. Trudno mi uwierzyć, że to prawda, ale nie mogę znaleźć wiele związanych z tym.

Moim prawdziwym powodem jest to, że doświadczamy bardzo wolnego czasu odpowiedzi w instrukcji delete przeciwko tabeli, która ma prawdopodobnie 15 powiązanych tabel. Ja zapytał naszego gościa z bazy danych i powiedział, że jeśli na polach jest klucz obcy, to działa jak indeks. Jakie masz z tym doświadczenie? Czy powinienem dodawać indeksy do wszystkich pól klucza obcego, czy są one po prostu zbędne?

Author: DrHouseofSQL, 2009-05-07

10 answers

Klucz obcy jest ograniczeniem, relacją między dwiema tabelami - nie ma to nic wspólnego z indeksem jako takim.

Ale jest wiadomym faktem, że indeksowanie wszystkich kolumn, które są częścią dowolnej relacji klucza obcego, ma sens, ponieważ poprzez relację FK, często będziesz musiał wyszukać odnoszącą się tabelę i wyodrębnić pewne wiersze na podstawie pojedynczej wartości lub zakresu wartości.

Więc warto indeksować wszelkie kolumny związane z FK, ale FK per se jest nie indeks.

Sprawdź doskonały artykuł Kimberly Tripp "Kiedy SQL Server przestał umieszczać indeksy na kolumnach kluczy obcych?".

 282
Author: marc_s,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-12-14 20:25:54

Wow, odpowiedzi są na całej mapie. Więc Dokumentacja mówi:

Ograniczenie klucza obcego jest kandydatem do indeksu, ponieważ:

  • Zmiany w ograniczeniach klucza podstawowego są sprawdzane z ograniczeniami klucza obcego w powiązanych tabelach.

  • Kolumny klucza obcego są często używane w kryteriach join, gdy dane z powiązanych tabel są łączone w zapytaniach przez dopasowanie kolumn w ograniczeniu klucza obcego jednej tabeli z podstawową lub unikalną kolumny kluczowe w drugiej tabeli. Indeks umożliwia Microsoft® SQL Server™ 2000 szybkie znajdowanie powiązanych danych w tabeli kluczy obcych. Jednak utworzenie tego indeksu nie jest wymogiem. Dane z dwóch powiązanych tabel można łączyć, nawet jeśli między tabelami nie są zdefiniowane żadne ograniczenia klucza głównego ani klucza obcego, ale relacja klucza obcego między dwiema tabelami wskazuje, że obie tabele zostały zoptymalizowane pod kątem łączenia w kwerendę, która używa kluczy jako swoich kryteriów.

Więc wydaje się całkiem jasne (chociaż dokumentacja jest nieco mętna), że w rzeczywistości nie tworzy ona indeksu.

 36
Author: Yishai,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 18:18:01

Nie, Nie ma indeksu implicit na polach klucza obcego, w przeciwnym razie dlaczego Microsoft powiedziałby "tworzenie indeksu na kluczu obcym jest często przydatne" . Twój kolega może pomylić pole klucza obcego w tabeli referującej z kluczem głównym w tabeli referowanej-klucze podstawowe do Utwórz indeks niejawny.

 17
Author: Michael Borgwardt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 18:11:55

Powiedzmy, że masz duży stół zwany zamówieniami, i mały stół zwany klientami. Istnieje klucz obcy od zamówienia do klienta. Teraz, jeśli usuniesz klienta, Sql Server musi sprawdzić, czy nie ma żadnych zamówień osieroconych; jeśli są, spowoduje to błąd.

Aby sprawdzić, czy są jakieś zamówienia, Sql Server musi przeszukać tabelę dużych zamówień. Teraz, jeśli istnieje indeks, wyszukiwanie będzie szybkie; jeśli nie ma, Wyszukiwanie będzie powolne.

Więc w tym przypadku powolne kasowanie może być wyjaśnione brakiem indeksu. Zwłaszcza jeśli Sql Server musiałby przeszukiwać 15 dużych tabel bez indeksu.

P. S. Jeśli klucz obcy ma na DELETE CASCADE, Sql Server nadal musi przeszukiwać tabelę zamówień, ale następnie usunąć wszelkie zamówienia, które odnoszą się do usuniętego klienta.

 6
Author: Andomar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 18:23:09

SQL Server automatycznie tworzy indeksy dla kluczy podstawowych, ale nie dla kluczy obcych. Utwórz indeks dla kluczy obcych. To pewnie warte kosztów.

 4
Author: Paul Sonier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-06 15:59:20

Klucze obce nie tworzą indeksów. Tylko alternatywne ograniczenia klucza(unikalne) i podstawowe ograniczenia klucza tworzą indeksy. Dotyczy to Oracle i SQL Server.

 4
Author: Sandeep Kanuri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-16 15:40:57

Nie wiem. Klucz obcy dodaje tylko ograniczenie, że wartość w kluczu potomnym jest również reprezentowana gdzieś w kolumnie nadrzędnej. Nie mówi to bazie danych, że klucz potomny również musi być indeksowany, tylko ograniczony.

 3
Author: Gandalf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 18:10:44

Ściśle mówiąc, klucze obce nie mają absolutnie nic wspólnego z indeksami, tak. Ale, jak wspomniałem wyżej, sensowne jest stworzenie takiego, aby przyspieszyć wyszukiwanie FK. W rzeczywistości, w MySQL, jeśli nie podasz indeksu w deklaracji FK, silnik (InnoDB) utworzy go dla ciebie automatycznie.

 2
Author: shylent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-07 18:22:33

W PostgeSql możesz sam sprawdzić indeksy jeśli naciśniesz \d tablename

Zobaczysz, że indeksy btree zostały automatycznie utworzone na kolumnach z kluczem podstawowym i unikalnymi ograniczeniami, ale nie na kolumnach z kluczami obcymi.

Myślę, że to odpowiada na twoje pytanie przynajmniej dla postgres.

 1
Author: Gregor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-07-07 13:24:50

Zauważyłem, że Entity Framework 6.1 wskazywany na MSSQL automatycznie dodaje indeksy do kluczy obcych.

 1
Author: Luke Puplett,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-02 14:32:02