Использование v$object_usageИсточник: ln
Этот короткая статья, в частности, посвящена применению представления 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> |