Должны ли таблицы Join обычно создаваться как индексные организованные таблицы (кластеризованные индексы)?

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

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

повышение скорости. Ты избегаешь смотреть вверх на кучу столов.

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

недостатки:

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

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

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

3 ответов


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

ассоциативные сущности с тремя таблицами (или более) обычно требуют значительно большего анализа.

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


я просто перечислю и расскажу о нескольких возможных решениях, которые, надеюсь, помогут вам решить. "Таблица объединения" содержит два или три столбца. Внешний ключ к левой таблице, скажем a и внешний ключ к правой таблице, скажем b. Необязательный столбец-это идентификатор строки для "таблицы объединения", скажем id.

Решение 1: Столбцы a,b. Нет кластеризованного индекса (куча), индексы (a,b) и (b,a)
Оба столбца хранятся в три места. Он поддерживает стремится на обоих a и b, и ищем 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 оба требуют поиска закладки. Оба!--0--> и b хранятся дважды на диске, один раз в собственном индексе и один раз в кластеризованном ключе. Это худшее решение, которое я мог думать.

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


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

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

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