Czy MySQL automatycznie indeksuje kolumny kluczy obcych?

261

Czy MySQL automatycznie indeksuje kolumny kluczy obcych?

Dónal
źródło

Odpowiedzi:

229

Tak, ale tylko na . Innodb jest obecnie jedynym dostarczonym formatem tabeli z zaimplementowanymi kluczami obcymi.

Grant Limberg
źródło
1
Czy masz powód, by sądzić, że MySQL kiedykolwiek zezwoli na klucze obce w nieindeksowanych kolumnach dla dowolnego innego typu tabeli?
Robert Gamble,
Naprawdę nie mogłem na to odpowiedzieć. Możesz poszukać mechanizmów magazynowania Maria i Falcon, które mają zostać wydane w MySQL 6.0 i sprawdzić, czy obsługują klucze obce w nieindeksowanych kolumnach.
Grant Limberg,
Najwyraźniej to nie jest prawda. Mam dużą tabelę (1 milion rekordów) i liczę (*) gdzie fkey =? zajmie 15 sekund. Dodano indeks do kolumny fkey, a teraz wszystko idzie poniżej sekundy.
AbiusX
Ten sam eksperyment z inną tabelą i 10 milionami rekordów. To jest Ofc MySQL 5.1 InnoDB. Tabela ma trzy pola, jedno jest liczbą całkowitą klucza podstawowego, drugie jest już zindeksowane. Trzeci był kluczem obcym do klucza podstawowego innej tabeli. Bez dodawania wyraźnego indeksu wyszukiwanie zajęło tutaj kilka sekund. Pokaż indeks z tabeli również nie wyświetlał na nim indeksu.
AbiusX
@AbiusX 5.1 jest prawdopodobnie za stary, patrz odpowiedź MrAlexander poniżej.
e2-e4
131

Najwyraźniej indeks jest tworzony automatycznie, jak określono w opublikowanym przez Roberta linku .

InnoDB wymaga indeksów kluczy obcych i kluczy referencyjnych, aby sprawdzanie kluczy obcych było szybkie i nie wymagało skanowania tabeli. W tabeli odwołań musi istnieć indeks, w którym kolumny klucza obcego są wymienione jako pierwsze kolumny w tej samej kolejności. Taki indeks jest tworzony automatycznie w tabeli odwołań, jeśli nie istnieje. (Jest to sprzeczne z niektórymi starszymi wersjami, w których indeksy musiały być tworzone jawnie lub tworzenie ograniczeń klucza obcego nie powiodło się.) Nazwa indeksu, jeśli podano, jest używana jak opisano wcześniej.

Ograniczenia InnoDB i ZAGRANICZNE

Justin Johnson
źródło
9
+1 znacznie lepsza odpowiedź niż wybrana, ponieważ stanowi dowód z dokumentów
Gaz_Edge 31.01.14
6
Cytowany tekst nie wydaje się już być dołączany do dokumentów MySQL, co sprawia, że ​​nie jest jasne, czy nadal jest to prawdą, czy nie.
Courtney Miles,
7
@ user2045006 możesz zapoznać się z doktorem 5.0 oraz doktorem 5.6, aby uzyskać dokładny cytowany tekst
sactiw
1
W obecnych dokumentach jest tylko niewielka zmiana w tekście (zakładam, że znaczenie jest podobne):InnoDB permits a foreign key to reference any index column or group of columns. However, in the referenced table, there must be an index where the referenced columns are the first columns in the same order.
Lucas Basquerotto
20

Tak, zobacz Ograniczenia InnoDB i ZAGRANICZNE .

Robert Gamble
źródło
4
Ta odpowiedź jest doskonałym przykładem tego, dlaczego odpowiedź nigdy nie powinna składać się wyłącznie z linku do możliwej odpowiedzi. W tej chwili linkowana strona w ogóle nie odpowiada na pytanie.
Mike
1
Dodaj wszystkie informacje do samej odpowiedzi zamiast zamieszczać tylko link
Nico Haase
11

Nie otrzymujesz indeksu automatycznie, jeśli wykonasz ALTER TABLE (zamiast CREATE TABLE), przynajmniej zgodnie z dokumentacją (link jest dla 5.1, ale jest taki sam dla 5.5):

[...] Kiedy dodajesz ograniczenie klucza obcego do tabeli za pomocą ALTER TABLE, pamiętaj, aby najpierw utworzyć wymagane indeksy.

Thomas Lundström
źródło
2
Próbowałem także na MySQL 5.6 i MariaDB 10 i ALTER TABLE stworzyłem indeks. Interesujące jest to, że mysqlindexcheck zgłosił ten indeks jako „indeks redundantny”. Próbowałem go usunąć, ale otrzymałem następujący błąd: „BŁĄD 1553 (HY000): Nie można upuścić indeksu„ nazwa_indeksu ”: potrzebne w ograniczeniu klucza obcego”. Tak więc nie można upuścić tego indeksu i zachować klucz obcy.
Ciprian Stoica,
Możesz zrewidować swoją odpowiedź. MySQL zawsze tworzy indeks przyspieszający sprawdzanie kluczy obcych, jeśli jeszcze nie istnieje . Dokumenty próbują powiedzieć, że tworzenie indeksów przed ograniczeniami klucza obcego może nieco przyspieszyć. Na przykład indeks klucza złożonego, który mógłby służyć jako indeks do sprawdzania klucza obcego, może być używany przez InnoDB zamiast automatycznego generowania nadmiarowego indeksu.
BMiner
7

Dla tych, którzy szukają cytatów z 5.7 dokumentów :

MySQL wymaga indeksów kluczy obcych i kluczy referencyjnych, aby sprawdzanie kluczy obcych było szybkie i nie wymagało skanowania tabeli. W tabeli odwołań musi istnieć indeks, w którym kolumny klucza obcego są wymienione jako pierwsze kolumny w tej samej kolejności. Taki indeks jest tworzony automatycznie w tabeli odwołań, jeśli nie istnieje. Ten indeks może zostać po cichu usunięty później, jeśli utworzysz inny indeks, którego można użyć do wymuszenia ograniczenia klucza obcego. nazwa_indeksu, jeśli jest podana, jest używana jak opisano wcześniej.

Fahmi
źródło
4

Jak stwierdzono, dotyczy to InnoDB. Na początku myślałem, że to dziwne, że wiele innych (w szczególności MS SQL i DB2) tego nie robi. Skany TableSpace są lepsze niż skany indeksowe tylko wtedy, gdy jest bardzo mało wierszy tabeli - tak więc w zdecydowanej większości przypadków klucz obcy chciałby być indeksowany. W pewnym sensie mnie to uderzyło - niekoniecznie musi to oznaczać, że musi to być samodzielny indeks (z jedną kolumną) - gdzie znajduje się w automatycznym indeksie FK MySQL. Być może dlatego MS SQL, DB2 (Oracle nie jestem pewien) itd. Pozostawiają to DBA; w końcu wiele indeksów na dużych tabelach może powodować problemy z wydajnością i przestrzenią.

Wolf5370
źródło
Poruszasz dobrą uwagę na temat indeksów kluczy złożonych; jednak MySQL automatycznie / po cichu upuści automatycznie wygenerowany indeks jednego klucza, jeśli nowo utworzony indeks klucza złożonego spełnia obowiązek szybkiego sprawdzania klucza obcego. Szczerze mówiąc, nie mam pojęcia, dlaczego MS SQL, DB2 i inni tego nie robią. Mają małą wymówkę. Nie mogę wymyślić przypadku użycia, w którym automatycznie wygenerowany indeks kluczy obcych byłby szkodliwy.
BMiner
2

Tak, Innodbpodaj to. Możesz wstawić nazwę klucza obcego po FOREIGN KEYklauzuli lub pozostawić ją, aby MySQL mógł utworzyć dla ciebie nazwę. MySQL automatycznie tworzy indeks o foreign_key_namenazwie.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action
Navrattan Yadav
źródło
0

Tak, Mysql indeksuje klucz obcy automatycznie podczas tworzenia tabeli, która ma klucz obcy do innego.

Giapnh
źródło
-2

Nie można automatycznie uzyskać klucza indeksu

ALTER TABLE (NAME OF THE TABLE) ADD INDEX (FOREIGN KEY)

Nazwa tabeli, którą utworzyłeś na przykład zdjęcia i KLUCZ OBCY photograph_id. Kod powinien być taki

ALTER TABLE photographs ADD INDEX (photograph_id);
Ali Raza
źródło