Индексирует ли MySQL столбцы внешнего ключа автоматически?

Ответы:

229

Да, но только на , В настоящее время Innodb является единственным форматом таблицы, в котором реализованы внешние ключи.

Грант Лимберг
источник
1
Есть ли у вас основания полагать, что MySQL когда-либо разрешит использование внешних ключей в неиндексированных столбцах для любого другого типа таблицы?
Роберт Гэмбл
Я действительно не мог ответить на это. Возможно, вы захотите посмотреть механизмы хранения Maria и Falcon, которые должны быть выпущены в MySQL 6.0, и посмотреть, поддерживают ли они внешние ключи в неиндексированных столбцах.
Грант Лимберг
Видимо, это не так. У меня есть большая таблица (1 миллион записей) и количество (*), где fkey =? займет 15 секунд. Добавлен индекс для столбца fkey, и теперь все идет меньше секунды.
AbiusX
Тот же эксперимент с другой таблицей и 10 миллионами записей. Это из MySQL 5.1 InnoDB. В таблице три поля, одно из которых является целым числом первичного ключа, а другое уже проиндексировано. Третий был внешним ключом первичного ключа другой таблицы. Без добавления явного индекса поиск занял здесь несколько секунд. Показывать индекс из таблицы также не показывали индекс по нему.
AbiusX
@AbiusX 5.1, вероятно, слишком стар, смотрите ответ господина Александра ниже.
e2-e4
131

Очевидно, индекс создается автоматически, как указано в ссылке, которую опубликовал Роберт .

InnoDB требует индексов для внешних ключей и ссылочных ключей, чтобы проверка внешних ключей могла быть быстрой и не требовала сканирования таблицы. В ссылочной таблице должен быть индекс, в котором столбцы внешнего ключа перечислены как первые столбцы в том же порядке. Такой индекс создается в ссылочной таблице автоматически, если он не существует. (Это отличается от некоторых более старых версий, в которых индексы должны были создаваться явно, иначе создание ограничений внешнего ключа завершилось бы неудачей.) Index_name, если дано, используется, как описано ранее.

Ограничения InnoDB и FOREIGN KEY

Джастин Джонсон
источник
9
+1 гораздо лучший ответ, чем тот, который выбран, поскольку предоставляет доказательства из документов
Gaz_Edge
6
Процитированный текст, похоже, больше не включается в документы MySQL, что делает неясным, правда ли это по-прежнему или нет.
Кортни Майлз
7
@ user2045006 вы можете обратиться к документу 5.0, а также документу 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

Да, см. Ограничения InnoDB и FOREIGN KEY .

Роберт Гэмбл
источник
4
Этот ответ является отличным примером того, почему ответ никогда не должен состоять только из ссылки на возможный ответ. В данный момент связанная страница не отвечает на вопрос вообще.
Майк
1
Пожалуйста, добавьте всю информацию к самому ответу вместо размещения только ссылки
Нико Хааз
11

Вы не получите индекс автоматически, если вы выполните ALTER TABLE (вместо CREATE TABLE), по крайней мере, в соответствии с документацией (ссылка для 5.1, но то же самое для 5.5):

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

Томас Лундстрем
источник
2
Я также попробовал на MySQL 5.6 и MariaDB 10 и ALTER TABLE создал индекс. Интересно, что mysqlindexcheck сообщил, что этот индекс является «избыточным индексом». Я попытался удалить его, но получил следующую ошибку: «ОШИБКА 1553 (HY000): Невозможно удалить индекс« имя_индекса »: требуется ограничение внешнего ключа». Таким образом, невозможно удалить этот индекс и сохранить внешний ключ.
Ciprian Stoica
Вы можете пересмотреть свой ответ. MySQL всегда создает индекс для ускорения проверки внешнего ключа, если он еще не существует . Документы пытаются сказать вам, что создание индексов до ограничения внешнего ключа может немного ускорить процесс. Например, составной индекс ключа, который мог бы служить индексом для проверок внешнего ключа, мог бы использоваться InnoDB вместо автоматической генерации избыточного индекса.
BMiner
7

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

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

Фахми
источник
4

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

Wolf5370
источник
Вы хорошо понимаете составные ключевые индексы; однако MySQL автоматически / без вывода сообщений отбросит автоматически сгенерированный индекс с одним ключом, если вновь созданный составной индекс ключа выполнит обязательство быстрой проверки внешнего ключа. Если честно, я понятия не имею, почему MS SQL, DB2 и другие не делают этого. У них мало оправданий. Я не могу вспомнить случай использования, когда автоматически сгенерированный индекс для внешних ключей был бы вредным.
BMiner
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 индексирует внешний ключ автоматически, когда вы создаете таблицу, которая имеет внешний ключ для другого.

giapnh
источник
-2

Невозможно получить ключ индекса автоматически использовать

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

Имя таблицы, которую вы создали, например, фотографии и КЛЮЧЕВОЙ КЛЮЧ, например photograph_id. Код должен быть таким

ALTER TABLE photographs ADD INDEX (photograph_id);
Али Раза
источник