Сравнение версий

Ключ

  • Эта строка добавлена.
  • Эта строка удалена.
  • Изменено форматирование.

...

Сервер Oracle будет хранить в индексе примерно следующее:

Это показывает, что в строках 8, 10 и 13 находится значение ANALYST, тогда как в строках 4, 6 и 7 — значение MANAGER. Также понятно, что пустых строк нет (индексы на основе битовых карт содержат записи для пустых значений — отсутствие такой записи в индексе означает, что пустых строк нет). Если необходимо посчитать, в скольких строках хранится значение MANAGER, индекс на основе битовых карт позволит сделать это очень быстро. Если необходимо найти все строки, в которых в столбце JOB хранится значение CLERK или MANAGER, достаточно просто скомбинировать соответствующие битовые карты из индекса.

Блок кода
sql
sql

-- bitmap индексы
drop table bt;

create table bt(n number, s varchar2(100), b number, i number);

select min(object_id), max(object_id), 0.5*(max(object_id)+min(object_id)) from all_objects;

delete from bt;

insert into bt(n, s, b, i) 
select object_id, object_name, case when object_id > 36116 then 1 else 2 end, case when object_id > 36116 then 1 else 2 end from all_objects;

create index ibt_i on bt(i);
create bitmap index ibt_b on bt(b);

select index_name, index_type, table_name, status, funcidx_status from user_indexes where table_name = 'BT';

analyze table bt compute statistics for table for all indexes for all indexed columns;

select i from bt where i = 1;
select b from bt where b = 1;

drop index ibt_i;
create bitmap index ibt_i on bt(i);

select * from bt where i = 0 or b = 0;
select * from bt where i = 1 or b = 0;

drop index ibt_i;
create index ibt_i on bt(i);

select /*+ index(bt ibt_b) */ * from bt where b = 1;
select /*+ index(bt ibt_i) */ * from bt where i = 1;

select count(*) from bt where b = 1;
select count(*) from bt where i = 1;

update bt set b = null where rownum < 100;
update bt set i = null where rownum < 100;

select * from bt where i is null;
select * from bt where b is null;
Индекс-организованные таблицы.

Индекс-оргранизованные таблицы - кластерные индексы, в индексе хранятся значения столбцов, выбранных для индекса, соединенные в одно значение. Индекс-оргранизованные таблицы имеют фиктивный rowid - значение индекса. ри запросе осуществляется быстрое сканирование индексов. Использование кластерных индексов способно заметно увеличить производительность поиска данных даже по сравнению с некластерными индексами, особенно при работе с последовательностями данных. В качестве кластерного индекса следует выбирать столбцы, наиболее часто задаваемые в качестве критериев поиска. При этом не следует использовать для индексирования слишком длинные столбцы. Кластерный индекс может включать несколько столбцов, но количество столбцов кластерного индекса следует по возможности свести к минимуму. Следует избегать создания кластерного индекса для часто изменяемых столбцов, так как сервер должен будет выполнять физическое перемещение всех данных в таблице, чтобы они находились в упорядоченном состоянии, как того требует кластерный индекс. Для интенсивно изменяемых столбцов больше подходит некластерный индекс.

Блок кода
sql
sql

-- индекс-организованные таблицы

drop table ih;

create table ih(p number constraint ipk primary key, s varchar2(100) null, n number null, nu number null constraint iun unique)
organization index;

select constraint_name, constraint_type, table_name, index_name from user_constraints where table_name = 'IH';
select index_name, index_type, table_name, status, funcidx_status from user_indexes where table_name = 'IH';

insert into ih(p, s, n, nu) select object_id, object_name, object_id, object_id from all_objects;

analyze table ih compute statistics for table for all indexes for all indexed columns;

commit;

select * from ih where s = 'h';

select s from ih where p = 123;

create index iind_s on ih(s);

analyze table ih compute statistics for table for all indexes for all indexed columns;

select * from ih where s = 'h';

-- фактически это не сегмент таблицы а сегмент индекса
select * from user_segments where segment_name in ('H', 'IH', 'PK', 'IPK');

-- отсутствие full table scan - вместо этого fast full scan
select * from ih;

-- отсутствие rowid в индексных таблицах
select rowid from ih where rownum < 10;

Принципы построения запросов для эффективного использования индексов.

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