Czy klucz obcy automatycznie tworzy indeks?


389

Powiedziano mi, że jeśli obcy klucz dwie tabele, SQL Server utworzy coś podobnego do indeksu w tabeli potomnej. Trudno mi uwierzyć, że to prawda, ale nie mogę znaleźć wiele związanych z tym zagadnień.

Moim prawdziwym powodem do tego jest to, że mamy bardzo wolny czas odpowiedzi w instrukcji delete na tabelę, która prawdopodobnie ma 15 powiązanych tabel. Zapytałem naszego gościa z bazy danych, a on odpowiada, że ​​jeśli w polach znajduje się klucz obcy, to działa jak indeks. Jakie jest twoje doświadczenie z tym? Czy powinienem dodawać indeksy do wszystkich pól kluczy obcych, czy są to po prostu niepotrzebne koszty ogólne?


Rozumiem to samo, co twój koleś z DB - że FK faktycznie tworzą indeks.
Vinnie,

9
Nie - FK NIE tworzy automatycznie indeksu. Tworzenie takiego ma sens, ale NIE jest wykonywane automatycznie przez SQL Server.
marc_s

47
wcale nie głupio jest o to pytać!
marc_s

5
Jeśli dostajesz powolne usuwanie i do tabeli, z której usuwane są inne tabele, prawdopodobnie uzyskasz wzrost wydajności poprzez indeksowanie kluczy obcych w innych tabelach. Wynika to z faktu, że gdy SQL usuwa wiersz, musi sprawdzić integralność referencyjną w wierszu. Aby to zrobić, należy oczywiście sprawdzić, czy nie istnieją żadne inne wiersze odnoszące się do usuwanego wiersza.
Noel Kennedy

3
Powiedziałbym, że facet z bazy danych, który nie wiedział o tym, musi poważnie potrzebować szkolenia. Ludzie bazy danych są odpowiedzialni za wydajność, ich zadaniem jest wiedzieć tego rodzaju rzeczy. To sugeruje rażącą niekompetencję.
HLGEM

Odpowiedzi:


343

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

Ale wiadomo, że indeksowanie wszystkich kolumn, które są częścią relacji klucza obcego, ma sens, ponieważ poprzez relację FK często trzeba wyszukać odpowiednią tabelę i wyodrębnić określone wiersze na podstawie pojedyncza wartość lub zakres wartości.

Dlatego warto indeksować dowolne kolumny związane z FK, ale FK jako taki nie jest indeksem.

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


Tak. Jestem prawie pewien, że PostgreSQL tworzy indeks. Jestem prawie pewien, że MySQL działa. Tworzenie indeksu ma sens, ale NIE JEST WYMAGANE. W końcu, po co odwoływać się do czegoś, jeśli za każdym razem, gdy DB idzie do sprawdzenia, musi wykonać skanowanie tabel?
MBCook

Powyższy artykuł jest niejasny, ponieważ serwer SQL lub inna baza danych nigdy nie umieszcza indeksu na FK.
vsingh,

7
@vsingh: dokładnie to próbuje przekazać artykuł - powszechne błędne przekonanie, że FK automatycznie tworzy indeks - nie robi tego.
marc_s,

5
@MBCook Nie, PostgreSQL czy nie (przynajmniej w 9.2 lub dowolnej wcześniejszej wersji) automatycznie utworzyć indeks na odwołującego stronie relacji klucza obcego z określonym REFERENCES. Automatycznie tworzy UNIQUEindeks dla ograniczenia PRIMARY KEYlub UNIQUEograniczenia i wymaga UNIQUEobecności indeksu dla odnośnego końca relacji klucza obcego, ale nie robi nic automatycznie dla końca referencyjnego , chociaż często dobrym pomysłem jest utworzenie go samodzielnie. Zobacz stackoverflow.com/questions/970562/…
Craig Ringer

16
Pomyłka może istnieć, ponieważ MySQL InnoDB zarówno wymaga, jak i automatycznie tworzy indeks po dodaniu klucza obcego - dev.mysql.com/doc/refman/5.5/en/…
humbads

42

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

Ograniczenie klucza OBCEGO jest kandydatem do indeksu, ponieważ:

  • Zmiany ograniczeń KLUCZ PODSTAWOWY są sprawdzane za pomocą ograniczeń KLUCZ OBCY w powiązanych tabelach.

  • Kolumny klucza obcego są często używane w kryteriach łączenia, gdy dane z powiązanych tabel są łączone w zapytaniach poprzez dopasowanie kolumn (-y) w ograniczeniu KLUCZ OBCY w jednej tabeli z podstawowymi lub unikatowymi kolumnami (kluczami) w drugiej tabeli. Indeks pozwala Microsoft® SQL Server ™ 2000 szybko znaleźć powiązane dane w tabeli kluczy obcych. Jednak utworzenie tego indeksu nie jest wymagane. Dane z dwóch powiązanych tabel można łączyć, nawet jeśli między tabelami nie zdefiniowano żadnych ograniczeń KLUCZ PIERWOTNY lub KLUCZ ZAGRANICZNY, ale relacja klucza obcego między dwiema tabelami wskazuje, że dwie tabele zostały zoptymalizowane do połączenia w zapytaniu, które używa kluczy jako jego kryteria.

Wydaje się więc dość jasne (choć dokumentacja jest nieco zamazana), że tak naprawdę nie tworzy indeksu.


5
Dokładnie - jest to KANDYDAT dla indeksu - ale nie jest automatycznie tworzone jako jeden! Właściwie całkiem jasne, IMHO :-)
marc_s

4
Znalazłem tę część mętną: „relacja klucza obcego między dwiema tabelami wskazuje, że dwie tabele zostały zoptymalizowane pod kątem połączenia w zapytaniu, które używa kryteriów jako kryteriów”. Powinno to brzmieć „... dwie tabele powinny być zoptymalizowane ...”
Yishai

18

Nie, nie ma niejawnego indeksu dla pól klucza obcego, w przeciwnym razie dlaczego Microsoft powiedziałby „Tworzenie indeksu na kluczu obcym jest często przydatne” . Twój kolega może być mylące pole klucza obcego w tabeli krajowego z klucza podstawowego w określonych do stołu - kluczy podstawowych należy utworzyć indeks niejawny.


co to jest „domniemany indeks”? czy to tylko sugeruje, że istnieje drzewo ab * bez jego tworzenia?
Stephanie Page

1
@Stephanie Page: To wyrażenie, które właśnie nadrobiłem, aby oznaczało indeks, który jest tworzony automatycznie. Jeśli zadeklarujesz klucz podstawowy, serwer SQL automatycznie go utworzy i zindeksuje. Ale nie jeśli deklarujesz klucz obcy (niektóre inne systemy DB tak robią).
Michael Borgwardt

7

SQL Server automatycznie tworzy indeksy dla kluczy podstawowych, ale nie dla kluczy obcych. Utwórz indeks dla kluczy obcych. Prawdopodobnie jest to narzut.


6

Załóżmy, że masz duży stół zwany zleceniami 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 tak, wywołuje 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, wyszukiwanie będzie wolne.

W takim przypadku powolne usuwanie można wyjaśnić brakiem indeksu. Zwłaszcza jeśli Sql Server będzie musiał przeszukać 15 dużych tabel bez indeksu.

PS Jeśli klucz obcy ma opcję USUŃ KASKADĘ, serwer Sql nadal musi przeszukiwać tabelę zamówień, ale następnie usunąć wszelkie zamówienia, które odnoszą się do usuniętego klienta.


Dokładnie - dlatego indeks na FK ma sens (przez większość czasu)
marc_s

1
Większość czasu? Wydaje się, że tak jest w przypadku usunięcia od rodzica. Jeśli przez większość czasu usuwasz od rodziców, to chyba prawda.
Stephanie Page

6

Klucze obce nie tworzą indeksów. Indeksy tworzą tylko alternatywne ograniczenia klucza (UNIQUE) i ograniczenia klucza podstawowego. Dotyczy to Oracle i SQL Server.


3

Nic mi nie wiadomo. Klucz obcy dodaje tylko ograniczenie, że wartość w kluczu potomnym jest również reprezentowana gdzieś w kolumnie nadrzędnej. Nie mówi bazy danych, że klucz potomny również musi być indeksowany, a jedynie ograniczony.


3

Ściśle mówiąc, klucze obce nie mają absolutnie nic wspólnego z indeksami, tak. Ale, jak zauważyli przede mną głośniki, sensowne jest stworzenie takiego, aby przyspieszyć wyszukiwanie FK. W rzeczywistości, w MySQL, jeśli nie określisz indeksu w deklaracji FK, silnik (InnoDB) utworzy go automatycznie.


3

W PostgeSql możesz samodzielnie 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.


Niestety nie zauważyłem, że pytanie dotyczy MS SQL Server, ale po opublikowaniu odpowiedzi. Prawdopodobnie nadal mógłby komuś pomóc ...
Gregor,

2

Zauważam, że Entity Framework 6.1 wskazany na MSSQL automatycznie dodaje indeksy do kluczy obcych.


Nie sądzę, aby tak się stało, jeśli ręcznie oflagujesz kolumnę jako część indeksu (np. Jeśli tworzysz indeks złożony dla kilku członków)
Rowland Shaw

0

InnoDB wymaga indeksów na temat kluczy obcych i kluczy odwołuje tak, że klucz obcy kontrole mogą być szybko i nie wymagają skanowania tabeli. W tabeli odwołań musi istnieć indeks, w którym kolumny kluczy obcych są wymienione jako pierwsze kolumny w tej samej kolejności.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.