Должны ли соединительные таблицы обычно создаваться как индексные организованные таблицы (кластерные индексы)? - PullRequest
6 голосов
/ 02 января 2012

Вообще говоря ... следует объединить таблицы (то есть ассоциативные таблицы) в виде индексированных организованных таблиц (Oracle), кластеризованных индексов (SQL Server) .... или простых старых таблиц кучи (с отдельными индексами в 2 столбцах).

Как я вижу, преимущества:

Улучшение скорости.Вы избегаете просмотра таблицы кучи.

Улучшение пространства.Вы полностью удаляете таблицу кучи, поэтому, вероятно, экономите ~ 30% пространства.

Недостатки:

Сканирование с пропуском индекса (относится только к Oracle) .. будет быстрее, чем полное сканирование таблицы, но медленнее, чем сканирование индекса.Таким образом, поиск во втором столбце составного ключа будет немного медленнее (Oracle), намного медленнее (MSSQL).

Полное сканирование индекса будет медленнее, чем полное сканирование таблицы, так что если в большинстве случаевОптимизатор на основе затрат выполняет хэш-соединения (которые не используют индексы) ... можно ожидать худшей производительности.(Предполагая, что СУБД сначала не фильтрует таблицы).

Что заставляет меня задаться вопросом, действительно ли нужны какие-либо типы индексов для таблиц объединения, если вы преимущественно собираетесь выполнять хэш-соединения.

Ответы [ 3 ]

3 голосов
/ 03 января 2012

Моё личное эмпирическое правило - создавать ассоциативные сущности из двух таблиц в виде таблиц с индексами, при этом ограничение первичного ключа - это «направление» доступа, которое я ожидаю использовать чаще.Затем я обычно добавляю уникальный индекс, чтобы покрыть обратный порядок ключей, поэтому во всех случаях оптимизатор должен иметь возможность доступа с уникальным сканированием или сканированием по дальности.

Три таблицы (или более)ассоциативные объекты обычно требуют значительно большего анализа.

Кроме того, оптимизатор будет использовать индексы с операциями хеш-соединения;как правило, быстрое полное сканирование, но индексы тем не менее.

3 голосов
/ 02 января 2012

Я бы просто перечислил и обсудил несколько возможных решений, которые, надеюсь, помогут вам принять решение.«Таблица объединения» содержит два или три столбца.Внешний ключ для левой таблицы, скажем 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 будет хорошим выбором по умолчанию.Я бы пошел на это, если бы другое решение не оказалось значительно лучше в тестах.

0 голосов
/ 03 января 2012

Я не знаком с терминологией Oracle, но для SQL Server вопрос сформулирован так, что это сбивает с толку.Для пояснения:

  • Кластерный индекс определяет физический порядок таблицы
  • Некластеризованный индекс - это, в основном, копия основной таблицы, упорядоченная по назначенным ключам
  • Куча - это таблица безИндекс любого вида.Все запросы к куче требуют сканирования.
  • Полное сканирование некластеризованного индекса выполняется быстрее, чем полное сканирование таблицы, при условии, что индекс уже, чем таблица, и вам не требуется поиск по закладкам.

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

...