Czy muszę tworzyć indeksy dla kluczy obcych w Oracle?

121

Mam stół Ai stół B. Aposiada klucz obcy do Bna B„s kluczem podstawowym B_ID.

Z jakiegoś powodu (wiem, że istnieją uzasadnione powody) nie używa indeksu, kiedy łączę te dwie tabele na kluczu.

Czy muszę osobno utworzyć indeks, A.B_IDczy też powinno to zapewniać istnienie klucza obcego?

aw crud
źródło

Odpowiedzi:

138

Samo ograniczenie klucza obcego nie zapewnia indeksu na Oracle - trzeba (i należy) go utworzyć.

DCookie
źródło
11
W niektórych bazach danych utworzenie ograniczenia klucza obcego tworzy również indeks ... tj. Jet Engine (pliki MSAccess, Firebird i MySQL)
bubi 23.0415
17
Ta odpowiedź jest bez znaczenia bez wyraźnego odniesienia do konkretnej implementacji bazy danych. Jasne, że pytanie jest otagowane, oracleale nie jest to od razu oczywiste, gdy wylądujesz tutaj z wyszukiwarki Google.
developerbmw
5
Mogę potwierdzić, że PostgreSQL - przynajmniej w czasie tego postu - nie robi tego automatycznie.
Dembinski
Ta sama odpowiedź dla SQL Server (2016, Azure ...), o ile wiem.
Pac0
Dlaczego należy utworzyć indeks klucza obcego w Oracle? Jakie są konsekwencje, jeśli tego nie zrobisz?
Đỗ Công Bằng
46

Utworzenie klucza obcego nie powoduje automatycznego utworzenia indeksu na A.B_ID. Zatem z punktu widzenia wydajności zapytań ogólnie sensowne byłoby utworzenie oddzielnego indeksu na A.B_ID.

Jeśli kiedykolwiek usuniesz wiersze w B, na pewno chcesz, aby A.B_ID był indeksowany. W przeciwnym razie Oracle będzie musiała wykonać pełne skanowanie tabeli na A za każdym razem, gdy usuniesz wiersz z B, aby upewnić się, że nie ma osieroconych rekordów (w zależności od wersji Oracle mogą również wystąpić dodatkowe skutki blokowania, ale te są zmniejszone w nowszych wersjach Oracle).

Justin Cave
źródło
1
A co z kolumnami PFK? na przykład, jeśli mam tabelę pośrednią dla relacji wiele-do-wielu, czy mam utworzyć indeks dla dwóch kolumn PFK tej tabeli?
Clamari
3
@Clamari - Jeśli C ma klucz podstawowy (A_ID, B_ID), klucz podstawowy zadba o możliwość usunięcia z A. Jeśli chcesz również mieć możliwość wydajnego usuwania z B, chciałbyś, aby indeks był włączony B_ID.
Justin Cave
25

Tylko po więcej informacji: Oracle nie tworzy indeksu automatycznie (tak jak to robi w przypadku unikalnych ograniczeń), ponieważ (a) nie jest wymagane wymuszanie ograniczenia oraz (b) w niektórych przypadkach go nie potrzebujesz.

Jednak w większości przypadków będziesz chciał utworzyć indeks (w rzeczywistości w Oracle Apex jest raport o „niezindeksowanych kluczach obcych”).

Ilekroć aplikacja musi mieć możliwość usunięcia wiersza w tabeli nadrzędnej lub zaktualizowania wartości PK (która jest rzadsza), DML ucierpi, jeśli nie będzie żadnego indeksu, ponieważ będzie musiał zablokować całą tabelę podrzędną.

Przypadkiem, w którym zwykle nie dodam indeksu, jest sytuacja, w której FK znajduje się w tabeli „danych statycznych”, która definiuje dziedzinę kolumny (np. Tabela kodów statusu), gdzie aktualizacje i usuwanie w tabeli nadrzędnej nigdy nie są wykonywane bezpośrednio przez aplikację. Jeśli jednak dodanie indeksu do kolumny daje korzyści dla ważnych zapytań w aplikacji, to indeks nadal będzie dobrym pomysłem.

Jeffrey Kemp
źródło
14

SQL Server nigdy nie umieszczał indeksów automatycznie w kolumnach kluczy obcych - zapoznaj się z doskonałym wpisem na blogu Kim Trippa na temat tła i historii tego miejskiego mitu.

Jednak zindeksowanie kolumn klucza obcego jest zwykle dobrym pomysłem - więc tak, zalecałbym upewnienie się, że każda kolumna FK jest poparta indeksem; niekoniecznie tylko na tej jednej kolumnie - może sensowne jest utworzenie indeksu na dwóch lub trzech kolumnach z kolumną FK jako pierwszą w nich. Zależy od scenariusza i danych.

marc_s
źródło
8

Ze względu na wydajność należy utworzyć indeks. Jest używany w operacjach usuwania na tabeli podstawowej (w celu sprawdzenia, czy usuwany rekord nie jest używany) oraz w połączeniach, w których zwykle używany jest klucz obcy. Tylko kilka tabel (nie tworzę ich w logach) może nie wymagać indeksu, ale prawdopodobnie w tym przypadku prawdopodobnie nie potrzebujesz również ograniczenia klucza obcego.

ALE

Istnieją bazy danych, które już automatycznie tworzą indeksy dla kluczy obcych. Silnik Jet (pliki Microsoft Access) Firebird MySQL

NA PEWNO

SQL Server Oracle

NIE

bubi
źródło
3
Dzięki za wspomnienie, że FIrebird SQL robi to automatycznie. Dokładnie tego szukałem.
user424855
1

Podobnie jak w przypadku wszystkiego, co dotyczy wyników, zależy to od wielu czynników i nie ma silnego punktu, np. W środowisku o bardzo wysokiej aktywności utrzymanie indeksu może być niedopuszczalne.

Najbardziej istotna wydaje się tutaj selektywność: jeśli wartości w indeksie byłyby silnie zduplikowane, może to dać lepszą wydajność w przypadku usunięcia indeksu (jeśli to możliwe) i umożliwienia skanowania tabeli.

onedaywhen
źródło
1

Ograniczenia UNIQUE, PRIMARY KEY i FOREIGN KEY generują indeksy, które wymuszają lub „cofają” ograniczenie (i są czasami nazywane indeksami zapasowymi). Ograniczenia typu PRIMARY KEY generują unikalne indeksy. Ograniczenia FOREIGN KEY generują nieunikalne indeksy. Ograniczenia UNIQUE generują unikalne indeksy, jeśli wszystkie kolumny nie dopuszczają wartości null, i generują nieunikalne indeksy, jeśli co najmniej jedna kolumna dopuszcza wartość null. Dlatego jeśli kolumna lub zestaw kolumn ma ograniczenie UNIQUE, PRIMARY KEY lub FOREIGN KEY, nie ma potrzeby tworzenia indeksu na tych kolumnach w celu zapewnienia wydajności.

Chinmai
źródło
Dokumenty, do których utworzyłeś łącze, dotyczą Derby, wbudowanej bazy danych Java, a nie Oracle.
Davos