{include file= $html_template_path.'header.html' }
|
Пример файла по которому дальше идет рассказ. Он к сожалению оказался не очень хорошо отсортирован. Тем не менее. Смотрим колонку cpu и находим запрос для которого на пересичении total и cpu стоит число 3337.29 (строка 516). Это число секунд. Вот сам запрос и план выполнения
SELECT pu_id,pu_anons_text,pu_rubric,UPPER(ru_name),pu_use_stat
FROM an_publ,an_rubrics
WHERE ru_id=pu_rubric AND pu_show=:SYS_B_0 AND pu_isanons=:SYS_B_1
AND pu_isanonsmain=:SYS_B_2;
ORDER BY pu_date DESC
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
0 SORT (ORDER BY)
0 HASH JOIN
0 INDEX GOAL: ANALYZED (FULL SCAN) OF 'AN_RUBRICS_I1'
(NON-UNIQUE)
0 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'AN_PUBL'
Видно что идет fullscan таблицы an_publ. Там 20,000 записей.
Делаю desc таблиц. Все поля с префиксом ru_
имеют отношение к an_rubrics. break on index_name; col column_name format a25; select index_name, column_name from user_ind_columns where table_name = 'AN_PUBL' order by index_name, column_position; Создадим ка мы индекс ! create index an_ind_rub_1 on an_publ (pu_rubric, pu_show, pu_isanons); И посмотрим на план выполнения еще раз:
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=9 Card=2 Bytes=114)
1 0 SORT (ORDER BY) (Cost=9 Card=2 Bytes=114)
2 1 NESTED LOOPS (Cost=7 Card=2 Bytes=114)
3 2 TABLE ACCESS (BY INDEX ROWID) OF 'AN_PUBL' (Cost=5 Car
d=2 Bytes=90)
4 3 BITMAP CONVERSION (TO ROWIDS)
5 4 BITMAP INDEX (SINGLE VALUE) OF 'AN_PUBL_I3'
6 2 TABLE ACCESS (BY INDEX ROWID) OF 'AN_RUBRICS' (Cost=1
Card=84 Bytes=1008)
7 6 INDEX (UNIQUE SCAN) OF 'SYS_C0034080' (UNIQUE)
Волшебство ! Берем следующий запрос, значение на пересечении total/cpu = 1827.30.
SELECT pu_id,UPPER(pu_head),pu_subhead,pu_author,pu_image,pu_annotation,
TO_CHAR(pu_date,:SYS_B_0),pu_rubric,pu_use_stat
FROM
an_publ WHERE pu_priority=:SYS_B_1
Rows Execution Plan
------- ---------------------------------------------------
0 SELECT STATEMENT GOAL: CHOOSE
0 TABLE ACCESS GOAL: ANALYZED (FULL) OF 'AN_PUBL'
Почему тут fullscan ? Посмотрим на распределение значение этого поля
SQL> select count(*), pu_priority from an_publ group by pu_priority;
COUNT(*) PU_PRIORITY
---------- -----------
20670 0
15 1
24 2
1 3
Классический случай bitmap индекса !. При таком распределении оптимизатор справедливо считает, что нужно просмотреть и индекс и потом таблицу. Это будет дороже чем просто просмотреть таблицу. Только bitmap индекс спасет нас.. Мы помним что по этому полю есть индекс. Но он обычный. Поэтому перестроим его SQL> drop index AN_IND_PUBL_PRIORITY; Index dropped. SQL> create bitmap index AN_IND_PUBL_PRIORITY on an_publ (pu_priority); Index created. Смотрим на запрос
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=CHOOSE (Cost=23 Card=15 Bytes=811
5)
1 0 TABLE ACCESS (BY INDEX ROWID) OF 'AN_PUBL' (Cost=23 Card=1
5 Bytes=8115)
2 1 BITMAP CONVERSION (TO ROWIDS)
3 2 BITMAP INDEX (SINGLE VALUE) OF 'AN_IND_PUBL_PRIORITY'
Давайте посмотрим как улучшилась ситуация. Снова воспользуемся tkporf.
|