Базы данных Oracle - статьи


Столбцы с небольшим количеством значений - часть 3


/p>

Обратите, в частности, внимание на суммарный объем индексов, - 191 Мбайт. Всего лишь один многостолбцовый индекс по тем же шести столбцам (даже с максимальным сжатием) займет минимум 430 Мбайт, а сколько процессорного времени потребуется на его построение, - я вообще не знаю, да и немногие системы позволят построить этот индекс в памяти, поскольку для этого требуется установить параметру sort_area_size значение около 900 Мбайт.

Итак, что же могут дать все эти битовые индексы? Рассмотрим запрос:

select count(facts) from t1 where eyes = 1 and sex = 1 and hair = 1 and town = 15 and age = 25 and work = 40;

На сокращенном наборе данных, который я подготовил, при вводе подсказки, требующей выполнения полного просмотра таблицы, запрос выполнялся одну минуту и 20 секунд (вернув ответ 8). Конечно, при реальном наборе фактических данных таблица была бы существенно больше, как и время выполнения.

При использовании полного шестистолбцового индекса объемом 430 Мбайт этот запрос выполнился бы, вероятно, за время, необходимое для выполнения около 10 физических чтений (один блок таблицы для каждой строки и пару дополнительных блоков индекса), - буквально за доли секунды.

При наличии заданных ранее битовых индексов запрос выполнялся пять секунд. Большая часть этого времени ушла на сканирования диапазонов индексов, требующие физического считывания блоков индекса в память. Фактический план выполнения представлен на рис. 5. SORT (AGGREGATE) TABLE ACCESS (BY INDEX ROWID) OF T1 BITMAP CONVERSION (TO ROWIDS) BITMAP AND BITMAP INDEX (SINGLE VALUE) OF I6 BITMAP INDEX (SINGLE VALUE) OF I5 BITMAP INDEX (SINGLE VALUE) OF I4

Рисунок 5. План выполнения.

В этом плане выполнения запроса следует отметить два интересных момента. Во-первых, сервер Oracle проигнорировал три "худших" (т.е., наименее избирательных) индекса. Во-вторых, хотя время выполнения - заметное, но размеры индексов настолько малы, что имеет смысл подумать об их размещении в достаточно большом KEEP-пуле, buffer_pool_keep (в Oracle 9 его размер задается параметром db_keep_cache_size), чтобы избежать физических чтений. Этот вариант вряд ли подходит для нескольких многостолбцовых индексов на основе B*-дерева, поддерживающих такие же запросы.

Давайте подумаем о проигнорированных индексах, - в плане может использоваться практически любое количество индексов на основе битовых карт. Я видел случаи, когда сервер Oracle использовал более пяти таких индексов (это предел для способа доступа and_equal при использовании одностолбцовых индексов на основе B*-дерева).

Три оставшихся индекса были проигнорированы не из-за какого-то искусственного ограничения. Стоимостной оптимизатор сравнил стоимость чтения каждого дополнительного индекса с достигаемой дополнительной точностью, и не выбрал их. Так что, индексы на основе битовых карт по классическому столбцу (пол) обычно игнорируются, несмотря на противоположные утверждения. (Удалите конструкцию work = 40 из запроса и убедитесь, что индекс по столбцу sex в этом случае используется).

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




Начало  Назад  Вперед



Книжный магазин