Я бы просто перечислил и обсудил несколько возможных решений, которые, надеюсь, помогут вам принять решение.«Таблица объединения» содержит два или три столбца.Внешний ключ для левой таблицы, скажем a
, и внешний ключ для правой таблицы, скажем b
.Необязательный столбец - это идентификатор строки для «объединенной таблицы», скажем id
.
Решение 1: Столбцы a,b
.Нет кластерного индекса (кучи), индексы на (a,b)
и (b,a)
Оба столбца хранятся в трех местах.Он поддерживает поиск по a
и b
, а поиск по b
не требует поиска по закладкам, поскольку a
является частью индекса (b,a)
.Достойный выбор, но тройное хранение кажется пустой тратой.Куча не используется, но должна поддерживаться во время запросов insert
и update
.
Решение 2: Столбцы a, b
.Кластерный индекс на (a,b)
, индекс на (b,a)
Все данные хранятся дважды.Может обслуживать поиск по a
и b
без поиска закладок.Это был бы подход наилучшей практики.Он обменивает дисковое хранилище на скорость.
Решение 3: Столбцы a, b
.Кластерный индекс на (a,b)
Все данные хранятся только один раз.Он может подавать запрос на a
, но не на b
.Переход от правой к левой таблице потребует сканирования таблицы.Это меняет скорость на дисковое пространство.(В вашем вопросе упоминается хеш-соединение. Хеш-соединение всегда выполняет полное сканирование.)
Решение 4: Столбцы id, a, b
.Кластерный индекс (id)
, индекс по (a)
и (b)
Поиск по a
или b
требует поиска по закладке.И a
, и b
хранятся дважды на диске, один раз в собственном индексе и один раз в кластерном ключе.Это худшее решение, которое я мог придумать.
Этот список ни в коем случае не является исчерпывающим.Решение 2 будет хорошим выбором по умолчанию.Я бы пошел на это, если бы другое решение не оказалось значительно лучше в тестах.