Чи індексує стовпці іноземних ключів MySQL автоматично?


Відповіді:


229

Так, але тільки на . На даний момент Innodb - це єдиний відвантажений формат таблиці, на якому реалізовані зовнішні ключі.


1
Чи є у вас підстави вважати, що MySQL коли-небудь дозволить сторонні ключі в неіндексованих стовпцях для будь-якого іншого типу таблиці?
Роберт Гембл

Я справді не міг відповісти на це. Можливо, ви захочете знайти механізми зберігання даних Maria та Falcon, які слід випустити в MySQL 6.0, і побачити, чи підтримують вони сторонні ключі в неіндексованих стовпцях.
Грант Лімберг

Мабуть, це неправда. У мене є велика таблиця (1 мільйон записів) і рахую (*) де fkey =? зайняло б 15 секунд. Додано індекс у стовпці fkey, і тепер справи проходять за секунду.
AbiusX

Той самий експеримент з іншою таблицею та 10 мільйонами записів. Це ofc MySQL 5.1 InnoDB. У таблиці є три поля, одне є цілим числом первинного ключа, інше вже індексовано. Третій - це зовнішній ключ до первинного ключа іншої таблиці. Не додаючи явного індексу, пошук тут зайняв кілька секунд. Показати показник з таблиці також не показав на ньому індекс.
AbiusX

@AbiusX 5.1, мабуть, занадто старий, див. Відповідь пана Александера нижче.
e2-e4

131

Мабуть, індекс створюється автоматично, як зазначено у посиланні, який опублікував Роберт .

InnoDB вимагає індексів зовнішніх ключів та посилальних ключів, щоб перевірка зовнішніх ключів була швидкою і не потребувала сканування таблиці. У таблиці посилань повинен бути індекс, де стовпці із зовнішнім ключем вказані як перші стовпці в тому ж порядку. Такий індекс створюється в референтній таблиці автоматично, якщо його не існує. (Це на відміну від деяких старих версій, в яких індекси повинні були бути створені явно або створення обмежень іноземних ключів не вдалося б.) Ім'я_індексу, якщо воно вказане, використовується як описано раніше.

Обмеження InnoDB та чужорідних ключів


9
+1 набагато краща відповідь, ніж та, яку вибрано, оскільки вона підтверджує документи
Gaz_Edge

6
Текст, який цитується, здається, більше не міститься в документах MySQL, що робить незрозумілим, чи все-таки це правда чи ні.
Кортні Майлз

7
@ user2045006 ви можете посилатися на doc 5.0 , а також на doc 5.6 для точного цитованого тексту
sactiw

1
У нинішніх документах лише незначна зміна тексту (я припускаю, що сенс схожий):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.
Лукас Баскетро

20

4
Ця відповідь є чудовим прикладом того, чому відповідь ніколи не повинна складатися лише з посилання на можливу відповідь. На даний момент пов’язана сторінка взагалі не відповідає на питання.
Майк

1
Будь ласка, додайте всю інформацію до самої відповіді, а не публікуйте лише посилання
Ніко Хааз

11

Ви не отримуєте індекс автоматично, якщо ви робите ALTER TABLE (замість CREATE TABLE), принаймні згідно з документами (посилання для 5.1, але це те саме для 5.5):

[...] Коли ви додаєте обмеження іноземного ключа до таблиці за допомогою ALTER TABLE, не забудьте спершу створити необхідні індекси.


2
Я також спробував на MySQL 5.6 і MariaDB 10 і ALTER TABLE створив індекс. Цікаво, що mysqlindexcheck повідомила, що цей індекс є "зайвим індексом". Я спробував скинути його, але отримав таку помилку: "ПОМИЛКА 1553 (HY000): Неможливо скинути індекс 'index_name': потрібен у обмеженні закордонного ключа". Отже, падати цей індекс неможливо і зберегти іноземний ключ.
Ciprian Stoica

Ви можете переглянути свою відповідь. MySQL завжди створює індекс для прискорення перевірки зовнішніх ключів, якщо такого ще не існує . Документи намагаються сказати вам, що створення індексів перед зовнішніми ключовими обмеженнями може трохи прискорити роботу. Наприклад, InnoDB може використовувати композитний індекс ключа, який може слугувати індексом для перевірки зовнішнього ключа, а не автоматично генерувати зайвий індекс.
БМінер

7

Для тих, хто шукає цитату з 5.7 документів :

MySQL вимагає індексів зовнішніх ключів та посилальних ключів, щоб перевірка зовнішніх ключів була швидкою і не потребувала сканування таблиці. У таблиці посилань повинен бути індекс, де стовпці із зовнішнім ключем вказані як перші стовпці в тому ж порядку. Такий індекс створюється в референтній таблиці автоматично, якщо його не існує. Цей індекс пізніше може бути беззвучно скинутий, якщо ви створите інший індекс, який можна використовувати для забезпечення обмеження зовнішнього ключа. index_name, якщо вказано, використовується як описано раніше.


4

Як зазначено, це робиться для InnoDB. Спочатку я подумав, що це дивно, що багато інших (зокрема MS SQL та DB2) цього не роблять. Сканування TableSpace краще лише, ніж індексне сканування, коли таблиць рядків дуже мало - тому в переважній більшості випадків іноземний ключ хочеться проіндексувати. Тоді мене це наче вдарило - це не обов'язково означає, що він повинен бути окремим індексом (в одному стовпчику) - там, де він знаходиться в автоматичному індексі FK MySQL. Отож, можливо, це є причиною того, що MS SQL, DB2 (Oracle я не впевнений у тому) і т. Д. Залишають це до DBA; адже всі численні індекси на великих таблицях можуть спричинити проблеми з продуктивністю та простором.


Ви підкреслюєте хорошу думку про складені індекси ключів; однак MySQL автоматично / безшумно скидає автоматично сгенерований індекс єдиного ключа, якщо новостворений складений індекс ключа виконає зобов’язання швидко перевіряти зовнішній ключ. Якщо чесно, я не маю поняття, чому MS SQL, DB2 та інші цього не роблять. У них мало виправдання. Я не можу придумати випадок використання, коли автоматично згенерований індекс на зовнішніх ключах був би шкідливим.
БМінер

2

Так, Innodbнадайте це. Ви можете поставити ім'я іноземного ключа після FOREIGN KEYпункту або залишити його, щоб MySQL створив ім'я для вас. MySQL автоматично створює індекс із foreign_key_nameназвою.

CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action

0

Так, Mysql індексує іноземний ключ автоматично, коли ви створюєте таблицю, в якій є іноземний ключ, до іншого.


-2

Автоматичне використання індексного ключа неможливо

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

Найменування таблиці, яку ви створили, наприклад, для фотографій та FOREIGN KEY, наприклад photograph_id. Код повинен бути таким

ALTER TABLE photographs ADD INDEX (photograph_id);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.