2010-04-11 4 views
14

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

+0

Внешние ключи на самом деле оказывают положительное влияние на производительность, учитывая его влияние на запросы между таблицами, используя объединения. Я не уверен, что это имеет отрицательный эффект. – Hanseh

+1

Хех, три из лучших ответов на этот вопрос - «преимущество в производительности», «нет разницы», «потеря производительности». –

ответ

15

Предполагая:

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

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

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

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

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

5

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

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

Найдено аналогичный запрос здесь: Does Foreign Key improve query performance?

3

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

1

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

3

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

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

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

Смежные вопросы