Много внешних ключей на одном столе - проблема производительности - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть большая таблица, состоящая в основном из перечисляемых значений (40 различных перечислений).

Каждое значение перечисления является внешним ключом для отдельной таблицы, потому что мне нужно разрешить пользователю настраивать имя и добавлять / удалять новые значения.Эти перечислимые таблицы очень малы, не более 20 значений в каждой.

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

В основной таблице содержится 2 миллиона строк , и она продолжает расти .

Как лучше всего представлять эти значения перечисления / повышать производительность?

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

1 Ответ

0 голосов
/ 20 апреля 2019

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

Какую цель служат вашим отношениям с ФК?Они обеспечивают согласованность базы данных, и это может быть полезно.Например, если в основной таблице у вас есть столбец с именем food_id, и он указывает на строку в таблице из шести строк с именем food, ваши отношения fk не позволят вам вставить значение, указывающее на восьмую строку..

Но для убедительности этой согласованности требуется много проверок значений.Это делает ваши вставки и обновления медленными.Вы знаете, что.

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

 SELECT main.item, main.item2, COALESCE (food.name, '--missing--') name
   FROM main
   LEFT JOIN food on main.food_id = food.food_id

При левом соединении будет отсутствовать значение для отсутствующего значения food_id, а COALESCE() покажет значение по умолчанию.

ИВаши операции вставки станут быстрыми.

...