Внедряет ли внешние ключи в MySQL снижение производительности

Я создаю приложение Ruby on Rails 2.3.5. По умолчанию Ruby on Rails не предоставляет внешние ключи, поэтому мне нужно сделать это вручную. Мне было интересно, если введение внешних ключей снижает производительность запросов на стороне базы данных, чтобы сделать это не стоит. Производительность в этом случае - мой первый приоритет, так как я могу проверить соответствие данных с кодом. Какова ваша рекомендация в целом? Вы рекомендуете использовать внешние ключи? и как вы предлагаете мне это измерить?

Ответ 1

Предполагая, что:

  • Вы уже используете механизм хранения, который поддерживает FK (то есть: InnoDB)
  • У вас уже есть индексы для соответствующих столбцов

Тогда я бы предположил, что вы получите лучшую производительность за счет обеспечения целостности MySQL. Обеспечение ссылочной целостности - это, в конце концов, то, для чего оптимизируются базы данных. Написание собственного кода для управления целостностью в Ruby будет медленным в сравнении.

Если вам нужно перейти от MyISAM к InnoDB, чтобы получить функциональность FK, вам нужно рассмотреть компромиссы между производительностью между двумя двигателями.

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

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

Ответ 2

В общем случае большее количество ключей (посторонних или иных) уменьшит производительность INSERT/UPDATE и повысит производительность SELECT.

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

Нашел аналогичный запрос здесь: Помогает ли внешний ключ повысить производительность запросов?

Ответ 3

Вы должны определить внешние ключи. В целом (хотя я не знаю специфики mySQL), на запросы не влияет (и когда в Oracle есть оптимизатор, например оптимизатор, основанный на затратах, он может даже иметь положительный эффект, поскольку оптимизатор может полагаться на информацию внешнего ключа для выбора лучших планов доступа). В зависимости от влияния на вставку и обновление, может быть влияние, но преимущества, которые вы получаете (ссылочная целостность и согласованность данных), значительно уменьшают влияние производительности. Конечно, вы можете создать систему, которая не будет работать вообще, но основная причина не будет, потому что вы добавили внешние ключи. И влияние на поддержание вашего кода, когда вы решите использовать какой-либо другой язык, или потому, что бизнес-правила слегка изменились, или потому, что новый программист присоединяется к вашей команде и т.д., Намного дороже, чем влияние производительности. Тогда моя рекомендация - да, идите и определите внешние ключи. Ваш конечный продукт будет более надежным.

Ответ 4

Рекомендуется использовать внешние ключи, поскольку это гарантирует вам согласованность данных (вы не хотите, чтобы сиротские строки и другие непоследовательные проблемы с данными).

Но в то же время добавление внешнего ключа приводит к некоторому результату. Предполагая, что вы используете INNODB в качестве механизма хранения, он использует кластерный индекс для ПК, где по существу хранятся данные вместе с PK. Для доступа к данным с использованием вторичного индекса требуется пройти через вторичное дерево индексов (где узлы содержат PK), а затем второй проход по кластерному индексу для фактического получения данных. Таким образом, любой DML в родительской таблице, в которой участвует FK, потребует два прохода над индексом в дочерней таблице. Конечно, влияние удара производительности зависит от объема данных, производительности вашего диска, ограничений памяти (кэширования данных/индексов). Поэтому лучше всего измерить его с учетом вашей целевой системы. Я бы сказал, что лучший способ его измерения - с вашими целевыми данными или, по крайней мере, некоторыми репрезентативными целевыми данными для вашей системы. Затем попробуйте запустить некоторые тесты с ограничениями FK и без них. Напишите сценарии на стороне клиента, которые генерируют одну и ту же нагрузку в обоих случаях.

Хотя, если вы вручную проверяете ограничения FK, я бы рекомендовал вам оставить это до mysql и позволить mysql обрабатывать его.

Ответ 5

Два пункта:
1. Вы уверены, что проверка целостности на уровне приложения будет лучше с точки зрения производительности?
2. Запустите собственное тестирование - тестирование, если у FK есть положительное или отрицательное влияние на производительность, должно быть почти тривиально.