В: Как я могу сказать: "MySQL, не беспокойтесь о создании индекса для этого внешнего ключа, но продолжайте проверять его содержимое в связанной таблице, которая в любом случае индексируется первичным ключом"
A: Нет, не могу. InnoDB требует подходящего индекса для поддержки применения ограничения внешнего ключа.
Рассмотрим обратную сторону ... если мы собираемся УДАЛИТЬ строку в родительской таблице, тогда InnoDB необходимо проверить ограничение внешнего ключа.
Это означает, что InnoDB необходимо проверить содержимое дочерней таблицы, чтобы найти строки, имеющие определенное значение в столбце внешнего ключа. По существу эквивалентно
SELECT ... FROM child_table c WHERE c.foreign_key_col = ?
И для этого InnoDB требует наличия индекса для child_table, в котором foreign_key_col
является ведущим столбцом.
Опции, предложенные в вопросе (отключение или удаление внешнего ключа), будут работать, потому что тогда InnoDB не будет применять внешний ключ. Но, как отмечено в вопросе, это означает, что внешний ключ не применяется. Который побеждает цель внешнего ключа. Код приложения может быть ответственным за обеспечение ссылочной целостности, или мы могли бы написать несколько триггеров ug-gghhh-ly (нет, мы не хотим туда идти).
Как уже отметил Гордон в своем (как обычно, отличном) ответе ... проблема не в том, чтобы удалить индекс в столбце внешнего ключа. фактическая проблема - неэффективный план выполнения. И наиболее вероятное решение этой проблемы - убедиться, что доступен более подходящий индекс.
Составные индексы - это путь. Индекс как это:
... ON child_table (foreign_key_col,tenant_id,...)
будет соответствовать требованию внешнего ключа, индекса со столбцом внешнего ключа в качестве ведущего столбца. И удалите (теперь избыточный) индекс только на singleton foreign_key_col.
Этот индекс также можно использовать для удовлетворения запроса, использующего ужасный план доступа к слиянию индексов. (Проверьте с помощью EXPLAIN.)
Также рассмотрите возможность добавления столбцов (например, foreign_key_col) к индексу, в котором tenant_id является ведущим столбцом
... ON child_table (tenant_id,...,foreign_key_col,...)
и сбросьте избыточный индекс в столбце синглтона tenant_id.