Oracle SQL: можно ли запрашивать строки в подмножестве, возвращаемые с помощью неуникального индекса, с помощью второго неуникального индекса? - PullRequest
1 голос
/ 20 июня 2011

Извините, если название озадачивает, мне трудно четко сформулировать мой вопрос.

Вот мой сценарий: У меня есть таблица с именем SUBSCRIBERS, которая имеет два неуникальных индекса. Индексированные столбцы: AREA_ID и SUBSCRIPTION_DATE.

Теперь я хочу (эффективно) сделать запрос для всех подписчиков в определенной области, которые подписались после указанной даты. Пример SQL:

SELECT *
FROM subscribers
WHERE area_id = 'areaID'
AND subscription_date > to_date(some_date)

Итак, скажем, чтобы выполнить этот запрос, Oracle сначала захватывает все строки с заданным areaID, и, скажем, это все еще очень большое количество строк. Сможет ли Oracle выполнить сканирование диапазона этого подмножества строк по дате подписки? Или же неуникальный индекс subscription_date применяется только к таблице FULL, что означает, что Oracle придется выполнять линейное сканирование по подмножеству?

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

Ответы [ 2 ]

4 голосов
/ 20 июня 2011

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

Индексы Oracle b-tree работают, сохраняя ключ и ROWID в таблице, в которой находится ключ. Чтобы объединить индексы, Oracle сначала преобразует их в растровый индекс, который по сути является двумерным массивом, который указывает, какая строка соответствует каким критериям. Затем он может сравнительно легко объединить два растровых индекса. Сложность этой операции заключается в первоначальном преобразовании индекса b-дерева в индекс растрового изображения. В принципе, ничто не мешает Oracle реализовать план запросов, который выбирает все ROWID из обоих индексов и выполняет пересечение двух наборов. Однако я предполагаю, что путь преобразования растровых изображений в целом более эффективен, потому что именно это реализовал Oracle.

У Джонатана Льюиса есть раздел о преобразованиях растровых изображений в его книге Основы Oracle на основе затрат.

Почти наверняка было бы более эффективно иметь составной индекс (AREA_ID, SUBSCRIPTION_DATE). Это позволит вам выполнить сканирование диапазона индекса для одного составного индекса. Запросы, которые только что имели предикат на AREA_ID, могли бы использовать этот составной индекс, поэтому индекс на AREA_ID, как правило, делался бы избыточным.

1 голос
/ 24 июля 2011

Ради полноты я хотел опубликовать этот отрывок с сайта Маркуса Винанда, который интуитивно объясняет, почему более чем один отдельный индекс b-дерева не может одновременно использоваться механизмом запросов:

... цепочка с одной осью поддерживает одно условие диапазона в качестве предиката доступа.Поддержка двух условий диапазона в качестве предиката доступа означала бы сканирование угла шахматной доски.Однако индекс B-Tree представляет собой цепочку - второй оси нет.

Источник: http://use -the-index-luke.com / sql / where-clause / search-for-range / index-merge-performance

И полезные диаграммы: http://use -the-index-luke.com / sql / anatomy / the-tree

Другими словами, индексы b-дерева создают только отсортированное дерево на основе одного поля данных.Узлы индекса - это n-кортежи, но записи индекса - это 1-кортежи.

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

На первый взгляд не уверен, какую сложность это может представлять, но я уверен, что это будет кошмар с несколькими индексами.Вам потребуется механизм для добавления дополнительных ссылок на местоположение индекса (каждый дополнительный индекс будет преобразовывать записи в вашем индексе из n-кортежей в (n + 1) -тупли), вам потребуется механизм для применения фильтра к другим индексам дляпропускайте местоположения без ссылок, и вам потребуется механизм для синхронизации ссылок по индексам при операциях создания / обновления / удаления в вашей таблице.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...