9 июня 2011 г.

oracle: Index Scans

http://aguppi.blogspot.com/2011/06/oracle-access-path.html
Что такое индекс oracle: Index

Типы Index Scans:

  • Index Unique Scans
  • Index Range Scans
  • Index Range Scans Descending
  • Index Skip Scans
  • Full Scans
  • Fast Full Index Scans
  • Index Joins
  • Bitmap Joins


Index Unique Scans

Возвращает один rowid.
Происходит, если выражение использует индекс, который содержит ограничение UNIQUE или PRIMARY KEY, которые гарантирую что будет возвращена только одна строка.

Hints
/*+ INDEX( tab_name idx1_name idx2_name ...) */

Этот хинт указывает оптимизатору использывать индекс, но не определённый путь индексного доступа.
Обычно не нужно указывать хинт для Index Unique Scans. Но если используем db link или таблица мала и оптимизатор выбирает Full Table Scan, то можно указать хинт.




Index Range Scans

Index Range Scans обычно используется, если есть индекс по столбцам, которые содержат не уникальные значения или выбирается диапазон (тогда может использоваться при уникальном индексе).

Пример, запрос который использует Index Range Scans:
SELECT order_status, order_id
  FROM orders
 WHERE order_date = :b1;

---------------------------------------------------------------------------------------
| Id  | Operation                   |  Name              | Rows  | Bytes | Cost (%CPU)|
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                    |     1 |    20 |     3  (34)|
|   1 |  TABLE ACCESS BY INDEX ROWID| ORDERS             |     1 |    20 |     3  (34)|
|*  2 |   INDEX RANGE SCAN          | ORD_ORDER_DATE_IX  |     1 |       |     2  (50)|
---------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ORDERS"."ORDER_DATE"=:Z)


Оптимизатор использует Index Range Scans в следующих выражениях:
  • col1 = :b1
  • col1 < :b1
  • col1 > :b1
  • AND комбинация вышеприведённых выражений
  • col1 like '%ASD' Wild-card searches should not be in a leading position. The condition col1 like '%ASD' does not result in a range scan.

Hints
/*+ INDEX( tab_name idx1_name idx2_name ...) */

Этот хинт указывает оптимизатору использывать индекс, но не определённый путь индексного доступа.

Предположим, что данные в столбце варьируются с разными значениями, по разбросу данных собрана гистограмма, т.е. оптимизатор знает о распределении данных.  Если используется bind variables, то оптимизатор не знает конкретного значения и поэтому выбирает Full Table Scans. Чтобы предотвратить это можно:
  • использовать значение(literal) вместо bind variables.
  • использовать хинт INDEX


Index Range Scans Descending

Index Range Scans Descending (сканирование по убыванию) идентично Index Range Scans, за исключением того, что данные возвращаются в порядке убывания.
По-умолчанию индексы расположены в порядке возрастания, но если нужно вернуть данные в порядке убывания используется Index Range Scans Descending.

Пример:
SELECT line_item_id, order_id
  FROM order_items
 WHERE order_id < :b1
 ORDER BY order_id DESC;

Оптимизатор использует Index Range Scans Descending если для  ORDER BY order_id DESC достаточно индекса.

Hints
/*+ INDEX_DESC( tab_name idx1_name idx2_name ...) */



Index Skip Scans

Skip scanning позволяет разделить составной индекс(индекс по нескольким столбцам) на маленькие под-индексы.
Такое сканирование используется в случаях, когда первый столбец составного индекса не входит в условия запроса. Другими словами, первый столбец пропускается (skipped) [при выполнении этой операции]. Первый(ведущий) столбец составного индекса не определён в запросе.
Кол-во под-индексов определяется кол-вом уникальных значений первого столбца.
Skip scanning выгоден, когда кол-во уникальных значений первого столбца мало, а кол-во уникальных значений ведомого столбца велико.

Пример

Таблица employees (sex, employee_id, address) с составным индексом по (sex, employee_id). Поле sex имее два уникальных значения M и F, получается два под-индекса.

Выполним запрос:

SELECT *
   FROM employees
WHERE employee_id = 101;

В нём сначала выполняет поиск по под-индексу со значением F, затем - со значением M.


Full Scans

Index full scan блок за блоком проходит по логической древовидной структуре индекса: начиная от корня (root) первой ветки (branch) первого листового блока (leaf block) и продолжает читать следующий листовой блок и так далее пока не останется больше листовых блоков(указатель на следующий leaf block в текущем leaf block будет равен null). Может происходить и нисходящий (descending) index full scan, в этом случае сканирование начинается с другой стороны дерева(правой). Считывает упорядоченные по индексному ключу данные.

Исключает сортировку, поскольку по одному блоку считывает упорядоченные по индексному ключу данные.

Отличие Full Scan от Fasts Full Index Scan  в том, что FFS позволяет мультиблочное чтение, быстрее, но данные не отсортированы, а Full Scan читает только по одному блоку.

A full scan is available if a predicate references one of the columns in the index. The predicate does not need to be an index driver. A full scan is also available when there is no predicate, if both the following conditions are met:
  •     All of the columns in the table referenced in the query are included in the index.
  •     At least one of the index columns is not null.


Full Scan может использоваться для устранения сортировки поскольку данные отсортированы по индексному ключу.



Fast Full Index Scans

Доступен только для режима оптимизатора CBO.

Fast Full Index Scan сканирует целый сегмент индекса используя многоблочное чтение, игнорируя при это логическую древовидную структуру индекса. Читает сразу листовые блоки, игнорирует branch blocks. Исходя из этого Fast Full Index Scan не гарантирует, что вернёт отсортированный индекс.

Отличие Full Scan от Fasts Full Index Scan  в том, что FFS позволяет мультиблочное чтение, быстрее, но данные не отсортированы, а Full Scan читает только по одному блоку.

Выполняется если индекс содержит все данные, которые возвращаются запросом, и по крайней мере один столбец в индексе имеет ограничение NOT NULL.

Fast Full Index Scans обращается только к индексу, к таблице обращаться нет необходимости.

Не устраняет операции сортировки, поскольку данные не отсортированы по индексному ключу.

Fast Full Index Scans не применяется для bitmap индексов.

Должна быть собрана статистика иначе оптимизатор может решить не использовать такой путь доступа.

Hints
/*+ INDEX_FFS( tab_name idx1_name) */



Index Joins

Доступен только для режима оптимизатора CBO.

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

Обращается только к индексу, к таблице обращаться нет необходимости, т.к. все данные представлены в индексе.

Не устраняет операции сортировки, поскольку данные не отсортированы по индексным ключам.

Hints
/*+ INDEX_JOIN( tab_name idx1_name idx2_name ...) */



Bitmap Joins

A bitmap join uses a bitmap for key values and a mapping function that converts each bit position to a rowid. Bitmaps can efficiently merge indexes that correspond to several conditions in a WHERE clause, using Boolean operations to resolve AND and OR conditions.

Bitmap access is available only with the CBO.