Насколько обязательно строить индекс для внешнего ключа (foreign key)?

«Насколько обязательно строить индекс для внешнего ключа (foreign key)?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Без индекса на столбце с внешним ключом:

  1. Проверка ограничений (CONSTRAINT) при операциях INSERT/UPDATE в дочерней таблице потребует полного сканирования (FULL SCAN) родительской таблицы для каждого ряда.
  2. Операции DELETE/UPDATE в родительской таблице (особенно с каскадными действиями CASCADE) будут выполняться крайне медленно, так как СУБД не сможет быстро найти зависимые строки в дочерней.
  3. Запросы с JOIN по этому ключу будут неэффективными.

Пример создания (MySQL/PostgreSQL):

-- Индекс часто создается автоматически при объявлении FOREIGN KEY.
-- Но лучше явно убедиться в его наличии.
ALTER TABLE `order_items` 
ADD INDEX `idx_order_id` (`order_id`),
ADD CONSTRAINT `fk_order_items_orders` 
    FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`)
    ON DELETE CASCADE;

Исключения, когда индекс может быть избыточным, крайне редки:

  • Таблица-справочник с очень малым и фиксированным количеством строк (например, statuses с 5 записями).
  • Таблица, в которую только пишут (лог-таблица) и никогда не читают с JOIN или WHERE по этому ключу (маловероятный сценарий).

Правило простое: внешний ключ → индекс.