Чи потрібно мені створювати в Oracle індекси зовнішніх ключів?


120

У мене є стіл Aі стіл B. Aмає зовнішній ключ Bна Bпервинний ключ «S, B_ID.

Чомусь (я знаю, що є законні причини), це не використання індексу, коли я приєдную ці дві таблиці на ключ.

Чи потрібно мені окремо створювати індекс про те, A.B_IDчи має існувати зовнішній ключ?

Відповіді:


137

Само обмеження зовнішнього ключа не забезпечує індекс Oracle - його потрібно (і слід) створити.


11
На деяких базах даних, що створюють обмеження на зовнішній ключ, створюється також індекс ... тобто Jet Engine (файли MSAccess, Firebird та MySQL)
bubi

17
Ця відповідь є безглуздою без явного посилання на певну реалізацію бази даних. Звісно, ​​що питання позначене тегом, oracleале це не відразу очевидно, коли ви приземляєтесь тут із пошуку Google.
developerbmw

5
Я можу підтвердити, що PostgreSQL - принаймні на час цієї публікації - не робить це автоматично.
Дембінський

Настільки ж мені відповідь і для SQL Server (2016, Azure ...), наскільки я знаю.
Pac0

Чому треба створити індекс на зовнішньому ключі за допомогою Oracle? Які наслідки не робити цього, будь ласка?
Đỗ Công Bằng

46

Створення іноземного ключа не автоматично створює індекс на A.B_ID. Тому, як правило, з точки зору виконання запитів має сенс створити окремий індекс на A.B_ID.

Якщо ви коли-небудь видаляєте рядки в B, ви обов'язково хочете, щоб A.B_ID був індексований. В іншому випадку Oracle доведеться проводити повне сканування таблиці на A щоразу, коли ви видаляєте рядок з B, щоб переконатися, що немає осиротілих записів (залежно від версії Oracle, можуть бути і додаткові наслідки блокування, але вони зменшуються в останніх версіях Oracle).


1
Що з колонками PFK? наприклад, якщо у мене є проміжна таблиця для відносин «багато-багато», я створюю індекс для двох стовпців PFK цієї таблиці?
Кламарі

3
@Clamari - Якщо у C є первинний ключ (A_ID, B_ID), первинний ключ би подбав про можливість видалення з А. Якщо ви також хочете мати можливість видалити з B, ви хочете, щоб індекс був увімкнено B_ID.
Джастін Печера

25

Для отримання додаткової інформації: Oracle не створює індекс автоматично (як це робиться для унікальних обмежень), оскільки (a) не потрібно застосовувати обмеження, і (b) в деяких випадках він вам не потрібен.

Однак більшу частину часу вам захочеться створити індекс (адже в Oracle Apex є звіт про "невкладені іноземні ключі").

Щоразу, коли програмі потрібно мати змогу видалити рядок у батьківській таблиці або оновити значення PK (що рідше), DML постраждає, якщо індекс не існує, оскільки він повинен буде заблокувати всю дочірню таблицю.

Випадок, коли я зазвичай вибираю не додавати індекс, - це FK - таблиця "статичних даних", яка визначає домен стовпця (наприклад, таблицю кодів статусу), де оновлення та видалення в батьківській таблиці ніколи не робиться безпосередньо додатком. Однак якщо додавання індексу в стовпчик дає переваги важливим запитам у додатку, то індекс все одно буде хорошою ідеєю.


14

SQL Server ніколи не ставив індекси на стовпці із зовнішніми ключами автоматично - ознайомтеся з чудовою публікацією в блозі Кіма Триппа на фоні та історії цього міського міфу.

Однак, як правило, добре проіндексувати стовпці із зовнішніми ключами - так, так, я б рекомендував переконатися, що кожен стовпець FK підкріплений індексом; не обов'язково для цього одного стовпця - можливо, це може мати сенс створити індекс на двох-трьох стовпцях за допомогою стовпця FK як першого там. Залежить від вашого сценарію та ваших даних.


8

З міркувань продуктивності слід створити індекс. Використовується в операціях видалення в основній таблиці (щоб перевірити, чи не використовується запису, яку ви видаляєте), а також при з'єднанні, в якому зазвичай бере участь іноземний ключ. Лише кілька таблиць (я не створюю їх у журналах) можуть бути такі, що не потребують індексу, але, мабуть, у цьому випадку, ймовірно, вам також не потрібне обмеження зовнішнього ключа.

АЛЕ

Є деякі бази даних, які вже автоматично створюють індекси на іноземних ключах. Jet Engine (файли доступу Microsoft) Firebird MySQL

ТОЧНО

SQL Server Oracle

НЕ


3
Thx для згадки, що FIrebird SQL робить це автоматично. Саме це я і шукав.
user424855

1

Як і у випадку, що стосується продуктивності, це залежить від багатьох факторів, і немає сріблястої кулі, наприклад, в умовах дуже високої активності збереження індексу може бути неприйнятним.

Найбільш помітним тут буде селективність: якщо значення в індексі будуть сильно дублюватися, то це може дати кращі показники, щоб скинути індекс (якщо це можливо) і дозволити сканування таблиці.


1

UNIQUE, PRIMARY KEY і FOREIGN KEY обмеження генерують індекси, які примушують або "назад" обмеження (а іноді їх називають резервними індексами). ОСНОВНІ КЛЮЧОВІ обмеження генерують унікальні індекси. ЗАБОРОНЕННЯ КОНТРОЛЬНОГО КЛЮЧУ генерують не унікальні індекси. Обмеження UNIQUE генерують унікальні індекси, якщо всі стовпці є ненульовими, і вони генерують унікальні індекси, якщо один або більше стовпців є нульовими. Тому, якщо стовпчик або набір стовпців мають УНІКАЛЬНЕ, ПЕРШИЙ КЛЮЧ або обмеження ЗОВНІШНЬОГО КЛЮЧУ на ньому, вам не потрібно створювати індекс цих стовпців для продуктивності.



Документи, з якими ви пов’язані, призначені для Derby, вбудованої бази даних Java, а не для Oracle.
Давос
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.