2012-01-01 5 views
6

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

На мой взгляд, если, преимущества:

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

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

Недостатки:

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

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

Это заставляет меня сомневаться в том, действительно ли нужны какие-либо индексы для таблиц Join, если вы преимущественно делаете Hash Joins.

+0

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

+2

reg «Полное сканирование индекса будет медленнее, чем сканирование полного стола»: у Oracle есть также INDEX FAST FULL SCAN, который в основном такой же быстрый, как полный доступ к таблице. См. Http://use-the-index-luke.com/sql/explain-plan/oracle/operations#index_fast_full_scan. См. Также мой комментарий reg. Hash Присоединяйтесь к индексированию ниже. –

+0

@MarkusWinand - Хорошая точка ... Спасибо за отличный сайт (IMO это самый сжатый источник агностиков dbms по индексам онлайн). – vicsz

ответ

3

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

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

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

3

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

+1

согласился, кроме хеш-соединения. Hash join может использовать индексы для независимых, где предикаты. Вероятно, нет никакого независимого, где предикаты в таком объединении, так что утверждение может быть правильным для этого случая. Но это зависит от фактического запроса. См. Http://use-the-index-luke.com/sql/join/hash-join-partial-objects –

+0

@Andomar: Мне нравится анализ. Как насчет ассоциации с тремя таблицами? Будут ли индексы на '(a, b, c) - clustered',' (b, c, a) 'и' (c, a, b) 'быть в порядке? –

0

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

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

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