Использование представления v$object_usageИсточник: ln
Этот короткий выпуск, в частности, посвящен применению представления v$object_usage для контроля использования индекса. По мотивам интересной публикации на сайте Тома Кайта. Надеюсь, регулярный выход рассылки теперь возобновится. Перерыв почти на месяц был вызван необходимостью срочно создавать учебные материалы для курса по администрированию Oracle 8i... Теперь работа эта закончена. Возможно, некоторые побочные результаты будут представлены и в этой рассылке. Много у меня в голове при этом прояснилось. Использование v$object_usageТом! Контролировать использование индекса в Oracle 9i можно, выполнив сначала оператор alter index xxx monitoring usage, начинающего процесс сбора соответствующей информации, а затем выполняя запросы к представлению v$object_usage. Какие операторы DDL или DML при этом будут генерировать 'YES' в столбце 'USED' этого представления? Друкгими словами, будут ли операторы 'select' считаться использующими индекс, или только update?.. Ответ Тома КайтаСтолбец будет иметь значение YES, если индекс использовался для ДОСТУПА к таблице, -- будь-то при изменении, слиянии (merge), удалении строк или при выполнении оператора SELECT. Этот столбец изменяется не потому, что "изменена" какая-то запись индекса -- это будет происходить при каждой вставке. Столбец устанавливается в YES, когда индекс используется для доступа к таблице. Рассмотрим пример ops$tkyte@ORA920.US.ORACLE.COM> create table t ( x int, 2 constraint t_pk primary key(x) ); Table created. ops$tkyte@ORA920.US.ORACLE.COM> insert into t 2 select rownum 3 from all_objects 4 where rownum <= 100 5 / 100 rows created. ops$tkyte@ORA920.US.ORACLE.COM> set echo off Теперь включим мониторинг индекса: ops$tkyte@ORA920.US.ORACLE.COM> select index_name, monitoring, used, start_monitoring, end_monitoring 2 from v$object_usage; no rows selected ops$tkyte@ORA920.US.ORACLE.COM> alter index t_pk monitoring usage 2 / Index altered. ops$tkyte@ORA920.US.ORACLE.COM> select index_name, monitoring, used, start_monitoring, end_monitoring 2 from v$object_usage; INDEX_NAME MONITORING USED START_MONITORING END_MONITORING ------------ ---------- ---- ------------------- ------------------- T_PK YES NO 10/05/2003 18:29:16 ops$tkyte@ORA920.US.ORACLE.COM> ops$tkyte@ORA920.US.ORACLE.COM> set echo off При использовании оптимизатора, основанного на правилах (RBO), как оно и будет по умолчанию, выборка count(*) идет не через индекс: ops$tkyte@ORA920.US.ORACLE.COM> set autotrace on explain ops$tkyte@ORA920.US.ORACLE.COM> select count(*) from t; COUNT(*) ---------- 100 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 SORT (AGGREGATE) 2 1 TABLE ACCESS (FULL) OF 'T' ops$tkyte@ORA920.US.ORACLE.COM> set autotrace off ops$tkyte@ORA920.US.ORACLE.COM> select index_name, monitoring, used, start_monitoring, end_monitoring 2 from v$object_usage; INDEX_NAME MONITORING USED START_MONITORING END_MONITORING ------------ ---------- ---- ------------------- ------------------- T_PK YES NO 10/05/2003 18:29:16 ops$tkyte@ORA920.US.ORACLE.COM> set echo off Как и выполнение оператора insert: ops$tkyte@ORA920.US.ORACLE.COM> insert into t values (-1); 1 row created. ops$tkyte@ORA920.US.ORACLE.COM> select index_name, monitoring, used, start_monitoring, end_monitoring 2 from v$object_usage; INDEX_NAME MONITORING USED START_MONITORING END_MONITORING ------------ ---------- ---- ------------------- ------------------- T_PK YES NO 10/05/2003 18:29:16 ops$tkyte@ORA920.US.ORACLE.COM> set echo off Но если проанализировать таблицу, при выборке count(*) индекс будет использоваться, и мы получим соответствующую запись: ops$tkyte@ORA920.US.ORACLE.COM> analyze table t compute statistics 2 / Table analyzed. ops$tkyte@ORA920.US.ORACLE.COM> set autotrace on explain ops$tkyte@ORA920.US.ORACLE.COM> select count(*) from t; COUNT(*) ---------- 101 Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=2 Card=1) 1 0 SORT (AGGREGATE) 2 1 INDEX (FULL SCAN) OF 'T_PK' (UNIQUE) (Cost=2 Card=101) ops$tkyte@ORA920.US.ORACLE.COM> set autotrace off ops$tkyte@ORA920.US.ORACLE.COM> select index_name, monitoring, used, start_monitoring, end_monitoring 2 from v$object_usage; INDEX_NAME MONITORING USED START_MONITORING END_MONITORING ------------ ---------- ---- ------------------- ------------------- T_PK YES YES 10/05/2003 18:29:16 ops$tkyte@ORA920.US.ORACLE.COM> |