|
Пример файла по
которому дальше идет рассказ. Он к
сожалению оказался не очень хорошо
отсортирован. Тем не менее. Смотрим колонку
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.
Поля с префиксом pu_
к an_publ. Смотрим какие индексы есть на an_publ
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;
/
INDEX_NAME COLUMN_NAME
------------------------------ -------------------------
AN_IND_PUBL_DATE PU_DATE
AN_IND_PUBL_INT_ANONS PU_ISANONS_INTERNAL
AN_IND_PUBL_ISANONS PU_ISANONS
AN_IND_PUBL_ORD PU_ORD
AN_IND_PUBL_PRIORITY PU_PRIORITY
AN_IND_PUBL_RUBRIC PU_RUBRIC
AN_PUBL_I3 PU_SHOW
PU_ISANONS
PU_ISANONSMAIN
AN_PUBL_I4 PU_DATE
PU_ANNOTATION
AN_PUBL_I4 PU_HEAD
PU_SUBHEAD
AN_PUBL_I5 PU_ORD
PU_RUBRIC
PU_SHOW
SYS_C0034681 PU_ID
17 rows selected.
Создадим ка мы индекс !
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.
|