Dsvolk > > Oracle > > Tuning > > Tkprof_example My Blog | Search | About
(Not Logged In)
[ welcome! ] [ news ] [ install ] [ jump-jet ] [ app ] [ rac ] [ papers ] [ dba ] [ dvp ] [ racdd4d ] [ oem ] [ statspack ] [ education ] [ tuning ] [ ias ] [ backup ] [ dataprotection ] [ security ] [ oid ] [ options ] [ integration ] [ sales ] [ sun ] [ linux ] [ consulting ] [ faq ]

tkprof_example

Соглашение о материалах на этом сайте

Мой oracle blog
true dsvolk!
Домашняя работа по tkprof  

Пример файла по которому дальше идет рассказ. Он к сожалению оказался не очень хорошо отсортирован. Тем не менее. Смотрим колонку 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.

 

Dsvolk > > Oracle > > Tuning > > Tkprof_example Last Modified: 25-03-2003 19:11