Category: Tuning / Performance

Hint OPT_PARAM



Leyendo algunas notas me encontré con un parámetro muy útil llamado OPT_PARAM, el cual nació en Oracle10gr2, pero del cual hay sólo notas en Metalink ...







Caso habitual , te has enfrentado a veces en la necesidad de probar algún parámetro y claro, debes hacer un ALTER SESSION o derechamente hacer una modificación al init o spfile y probar los cambios..

Pues este HINT sirve para eso, comprobar el estado de un cambio de parámetros a nivel de sentencia SQL, con lo cual podemos probar online cualquier modificación, el cambio sólo sirve para aquellos parámetros que hacen una modificación al optimizador, no se puede modificar por ejemplo la ruta de los archives |-|




¿Cómo funciona? Con los siguientes ejemplos , les quedará claro el como..

1) Creamos 2 tablas de ejemplo , llamadas t y t2
create table t as select * from dba_objects;
create table t2 as select * from dba_objects;


2) Hacemos un simple join entre ambas tablas , al ver el plan de ejecución , podremos observar que hace un HASH JOIN

SQL> select t.owner
  2    from t ,
  3         t2
  4   where t.object_id = t2.object_id;

72659 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 2663495741

---------------------------------------------------------------------------
| Id  | Operation          | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |      | 63977 |  2686K|   569   (1)| 00:00:07 |
|*  1 |  HASH JOIN         |      | 63977 |  2686K|   569   (1)| 00:00:07 |
|   2 |   TABLE ACCESS FULL| T2   | 63977 |   812K|   283   (1)| 00:00:04 |
|   3 |   TABLE ACCESS FULL| T    | 69344 |  2031K|   284   (1)| 00:00:04 |
---------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("T"."OBJECT_ID"="T2"."OBJECT_ID")

Note
-----
   - dynamic sampling used for this statement (level=2)


3) Ahora vamos a deshabilitar el HASH JOIN , con el OPT_PARAM , ejecutamos el plan de ejecución

SQL> select /*+ opt_param('hash_join_enabled','false') */
  2         t.owner
  3    from t ,
  4         t2
  5   where t.object_id = t2.object_id;

72659 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 219814191

------------------------------------------------------------------------------------
| Id  | Operation           | Name | Rows  | Bytes |TempSpc| Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT    |      | 63977 |  2686K|       |  1447   (1)| 00:00:18 |
|   1 |  MERGE JOIN         |      | 63977 |  2686K|       |  1447   (1)| 00:00:18 |
|   2 |   SORT JOIN         |      | 63977 |   812K|  2520K|   592   (2)| 00:00:08 |
|   3 |    TABLE ACCESS FULL| T2   | 63977 |   812K|       |   283   (1)| 00:00:04 |
|*  4 |   SORT JOIN         |      | 69344 |  2031K|  5448K|   855   (1)| 00:00:11 |
|   5 |    TABLE ACCESS FULL| T    | 69344 |  2031K|       |   284   (1)| 00:00:04 |
------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   4 - access("T"."OBJECT_ID"="T2"."OBJECT_ID")
       filter("T"."OBJECT_ID"="T2"."OBJECT_ID")

Note
-----
   - dynamic sampling used for this statement (level=2)


Según la documentación de Oracle , los únicos parámetros modificables a través del OPT_PARAM son OPTIMIZER_DYNAMIC_SAMPLING, OPTIMIZER_INDEX_CACHING, OPTIMIZER_INDEX_COST_ADJ, OPTIMIZER_SECURE_VIEW_MERGING y STAR_TRANSFORMATION_ENABLED, pero en realidad se pueden modificar parámetros normales y ocultos, por ejemplo _FIX_CONTROL , HASH_JOIN_ENABLED, etc


La documentación oficial del hint OPT_PARAM
http://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#SQLRF51119


Espero les sirva

by Ligarius
22.05.13. 12:15:32. 446 words, 6577 views. Categories: Tuning / Performance ,

Retención de los snapshots e información de las DBA_HIST



Esta consultando información desde la tabla DBA_HIST_SEG_STAT y sólo encontre información de la última semana, pero la verdad esto no me sirve de mucho y quiero que el período a consultar sea un poco mayor...

¿A qué se debe que tenga tan poca retención? He aquí la explicación




La información que se visualiza en las DBA_HIST se carga cuando se están generando los Snapshots del AWR y se elimina cuando estos últimos se purgan, o sea, dependen directamente del intervalo de tiempo en donde se recogen estos Snapshots de AWR y se mantienen en línea el tiempo de retención seteado para los Snaps de AWR.


Para saber que seteo nosotros poseemos en nuestras bases de datos podemos ejecutar la siguiente consulta

select
extract( day from snap_interval) *24*60+
extract( hour from snap_interval) *60+
extract( minute from snap_interval ) "Intervalo entre Snaps",
extract( day from retention) *24*60+
extract( hour from retention) *60+
extract( minute from retention ) "Periodo de retencion seg" ,
extract( day from retention) "Periodo de retencion dias"
from dba_hist_wr_control;



Cuyo resultado se visualizaría de la siguiente forma

Intervalo entre Snaps Periodo de retencion seg Periodo de retencion dias
--------------------- ------------------------ -------------------------
15 86400 60



¿Cuál es el mejor período de retención e intervalo para tomar los Snapshots?

Aquí todo depende, ¿de qué depende? Pues del tamaño de nuestro tablespace SYSAUX, de que tanta carga tenga nuestra base de datos, etc, etc.

Pero podemos imaginarnos el tamaño que podría necesitar, para ello consultamos nuestro AWR dentro del tablespace SYSAUX, para ello ejecutamos la siguiente consulta

SQL> r
1 SELECT occupant_name, schema_name, move_procedure,
2 space_usage_kbytes
3 FROM v$sysaux_occupants
4* ORDER BY 1



El dato que nos interesa , aparecería de la siguiente forma

OCCUPANT_NAME SCHEMA_NAME MOVE_PROCEDURE SPACE_USAGE_KBYTES
------------------------------ -------------------- ----------------------------------- ------------------
SM/AWR SYS 10432448



Aquí podemos apreciar claramente cuanto es lo que usan nuestros snapshots para el período de tiempo de retención

Otra forma de obtener los datos que necesitamos , ejecutando el siguiente comando desde SQL*Plus

@?/rdbms/admin/awrinfo.sql



Dentro del reporte que se obtiene , podemos ver el intervalo en que se toman los snapshots y el período de retención, para ello buscamos el punto (6)

(6) AWR Control Settings - interval, retention



También podemos buscar el tamaño calculado para nuestros snapshots , con lo cual podemos saber de una manera óptima cuanto es el tamaño en Gb o en MB que necesitamos si queremos ampliar nuestro período de retención para los snapshors del AWR.

Dentro de la salida del awrinfo.sql , existe un punto llamado

*************************************
(2) Size estimates for AWR snapshots
*************************************
|
| Estimates based on 60 mins snapshot INTERVAL:
| AWR size/day 27.7 MB (1,182 K/snap * 24 snaps/day)
| AWR size/wk 193.9 MB (size_per_day * 7) per instance
|
| Estimates based on 4 snaps in past 24 hours:
| AWR size/day 4.6 MB (1,182 K/snap and 4 snaps in past 24 hours)
| AWR size/wk 32.3 MB (size_per_day * 7) per instance
|



Donde podemos ver claramente cuanto pesan nuestros Snaps por día.

Una vez que hemos realizado los cálculos necesarios para chequear el tamaño del tablespace SYSAUX , procedemos a cambiar el intervalo de retención y el intervalo de captura de nuestros snapshots de AWR, para ello ejecutamos el siguiente package

execute dbms_workload_repository.modify_snapshot_settings (
interval => xx,
retention => xxxxx );



Donde le indicamos el intervalo para sacar snapshots en minutos y el período de retención en segundos, ejemplo :

Para sacar los snapshots cada 60 minutos con una retención de 69 días

1 begin
2 dbms_workload_repository.modify_snapshot_settings (interval => 60,retention => 100000 );
3* end;
SQL> /

PL/SQL procedure successfully completed.


Una vez modificado podemos consultar nuevamente el seteo

SQL> select
2 extract( day from snap_interval) *24*60+
3 extract( hour from snap_interval) *60+
4 extract( minute from snap_interval ) "Intervalo entre Snaps",
5 extract( day from retention) *24*60+
6 extract( hour from retention) *60+
7 extract( minute from retention ) "Periodo de retencion seg" ,
8 extract( day from retention) "Periodo de retencion dias"
9 from dba_hist_wr_control;

Intervalo entre Snaps Periodo de retencion seg Periodo de retencion dias
--------------------- ------------------------ -------------------------
60 100000 69

Espero les sirva...

by Ligarius
06.05.13. 14:21:52. 688 words, 5270 views. Categories: Base de datos, Tuning / Performance ,

Cosas sobre sys.col_usage$



La tabla sys.col_usage$ almacena de forma automática a través del proceso SMON , la cantidad de veces que alguna columna se ocupa en una claúsula WHERE de una sentencia SQL, si esto lo miramos con un poco de altura de miras, no solamente veremos que es información estadística que se almacena para siempre y por siempre, he acá algunas cosas para tener en cuenta



Desde está información por ejemplo nosotros podríamos chequear cual es el mejor índice o cuales son los índices necesarios en una tabla de acuerdo a los filtros que tenga..

La estructura de la tabla

SQL> desc sys.col_usage$
Name Null? Type
----------------------------------------- -------- -----------------------
OBJ# NUMBER
INTCOL# NUMBER
EQUALITY_PREDS NUMBER
EQUIJOIN_PREDS NUMBER
NONEQUIJOIN_PREDS NUMBER
RANGE_PREDS NUMBER
LIKE_PREDS NUMBER
NULL_PREDS NUMBER
TIMESTAMP DATE



La explicación de sus columnas

OBJ# : Es el id del objeto (tabla principal) , este id lo podemos ubicar en DBA_OBJECTS.OBJECT_ID

INTCOL# : Es el id de la columna, se puede obtener su nombre desde DBA_TAB_COLUMNS.COLUMN_ID

EQUALITY_PREDS : Es la cantidad de filtros en el where del tipo
ej : where campo1 = -literal-

EQUIJOIN_PREDS : Es la cantidad de filtros en el where del tipo
ej : where tabla1.campo1 = tabla2.campo1

NONEQUIJOIN_PREDS : Es la cantidad de filtros en el where del tipo
ej : where tabla1.campo1 =! tabla2.campo1

RANGE_PREDS : Es cuando el campo es utilizado dentro de una claúsula BETWEEN

LIKE_PREDS : Es cuando el campo es utilizado dentro de una claúsula LIKE

NULL_PREDS : Es cuando se consulta por si el campo es nulo o no nulo
ej : where tabla1.campo1 is null

TIMESTAMP : Es la fecha en que se produjo la última utilización de fitros (where) para un objeto en partícular.



Una forma más amistosa de chequear los datos de la tabla SYS.COL_USAGE$ es mediante la siguiente consulta, que entrega los nombres de los objetos y claro, el nombre de la columna de forma inmediata

select oo.name owner,
o.name,
c.name column_name,
u.equality_preds,
u.equijoin_preds,
u.nonequijoin_preds,
u.range_preds,
u.like_preds,
u.null_preds,
u.timestamp
from sys.col_usage$ u ,
sys.obj$ o ,
sys.user$ oo,
sys.col$ c
where o.obj# = u.obj#
and oo.user# = o.owner#
and c.obj# = u.obj#
and c.col# = u.intcol#
AND o.name = 'nombre del objeto a consultar'



Esta tabla también tiene la gracia que a partir de ahí Oracle puede generar los histogramas cuando se ocupa el package DBMS_STATS con el parámetro METHOD_OPT => 'FOR all COLUMNS SIZE auto', o sea, le indicamos a él que calcule la cantidad de buckets para nuestro histograma (de 1 a 256)

Si hacemos lo siguiente

- Generamos una tabla
- Cargamos datos en la tabla
- Generamos histogramas

No estaría correcto, ya que los histogramas no se van a generar con información fidedigna , a menos que haya información en la SYS.COL_USAGE$ y solamente habrá información en esa tabla si comenzamos a utilizar filtros en la consultas que ocupan esa tabla

A partir de Oracle10g la información se carga a esta tabla cuando se produce una toma de estadísticas o se puede hacer ejecutando la siguiente instrucción

exec dbms_stats.flush_database_monitoring_info;



La carga de está información se realiza con una frecuencia de minutos , quizás podríamos decir unos 15 , o cuando se hace alguna actualización o inserción , como podemos apreciar de distintas fuentes está tabla SYS.COL_USAGE$ se actualiza

by Ligarius
04.03.13. 07:32:11. 610 words, 3758 views. Categories: Base de datos, Tuning / Performance ,

Toma de estadísticas a los objetos Fixed (X$) (Statistics on Fixed Tables)



Hola, les voy a presentar un pequeño texto relacionado con la toma de estadísticas a las tablas Fixed de Oracle, denominadas X$ , su importancia es trascendental y sobre todo , sus estadísticas... que pueden repercutir en tiempo de respuesta muy malos cuando no están al día o cuando sencillamente no están actualizadas


Obs : Puse la foto de Milla Jovovich pues es simplemente la perfección ...no tiene nada que ver con la nota , no creo que produzca incomodidad :>>


Los objetos Fixed en Oracle corresponden a aquellas tablas llamadas las X$ y a sus correspondientes índices, estas tablas tienen la particularidad de que son cargadas en la SGA al momento de realizar el startup de la instancia y son aquellas tablas en donde se almacena la información en tiempo real de lo que está sucediendo en la base de datos, estas tablas poseen algunas características muy particulares, por ejemplo :


a) Son tablas que no poseen bloques (físicos) dado que solamente se cargan en memoria
b) Son aquellas tablas que sirven de base para las V$ y GV$ , por ende, el hecho de que no tengan estadísticas al día repercuten en toda la base de datos.



La actividad de recolección de estadísticas no se hace de forma automática, por ende siempre tiene que formar parte de un plan de toma de estadística general, para lo anterior , se debe ocupar el siguiente package :

BEGIN
DBMS_STATS.GATHER_FIXED_OBJECTS_STATS;
END;



Este procedimiento toma las estadísticas desde las tablas X$ , el porcentaje está dado internamente por ende no es un factor a tomar en cuenta cuanto es lo que se analiza.


Cabe mencionar que como son tablas en memoria y la data que muestran representan la carga del sistema, no es buena idea hacer una recolección de datos en momentos en donde la carga de la base de datos sea mínima, pues los planes de ejecución creados por el CBO a partir de está información pueden no ser los más óptimos.


Por lo anterior se recomienda que la toma de estadísticas sobre las tablas X$ se haga en un momento de carga de la base de datos, si tenemos a mano una aplicación para generar gráficos de carga de nuestra base o gráficos de los mayores eventos de espera , podemos tomar un tramo en el cual no esté el "peak" de uso , para no provocar contensión.




El anterior gráfico viene de una herramienta muy útil y que es OPEN SOURCE, pronto estaremos dando detalles de ella en una nota ;)


Un período de carga favorable para la toma de estadística (Fixed Tables) en este nodo sería el horario comprendido entre las 00:00 y 04:00 , después de lo cual se puede ejecutar una toma de estadísticas para el horario 19:00 y 00:00, esto es para que se tabulen los resultados de la toma de estadística en el primero intervalo de tiempo e irse acercando lo más posible a la hora de mayor carga del sistema.



Datos actuales

Se puede obtener la cantidad de tablas X$ con estadísticas simplemente ejecutando el siguiente comando :

SELECT count(*) , to_char(last_analyzed,'yyyy-mm')
FROM dba_tab_statistics
WHERE table_name like 'X$%'
GROUP BY to_char(last_analyzed,'yyyy-mm')
ORDER BY 2


O si lo prefieren , mediante la siguiente consulta

SELECT owner
, table_name
, last_analyzed
FROM dba_tab_statistics
WHERE table_name IN
(SELECT name
FROM v$fixed_table
WHERE type = 'TABLE'
)
ORDER BY last_analyzed;



Consideraciones a tener en cuenta

Hay ciertas consideraciones y puntos que se deben tener cuenta al momento de sacar estadísticas sobre las tablas X$

a) Se debe tomar estadísticas a este nivel, cada vez que se haga un upgrade del aplicativo

b) Cada vez que se haga algún cambio a nivel de base de datos, por ejemplo cambio de parámetros, cambio del tamaño de la SGA , etc , etc

c) El hecho de que haya estadísticas malas o simplemente no existan estadísticas para este tipo de componentes, puede generar planes de ejecución muy malos, sobre todo cuando se trata de acceder a áreas de memoria como la Shared Pool, ya que se pueden provocar encolamientos por la “serialización” al tratar de consultar los datos allí residentes.

d) Cada vez que se ejecuta el package para tomar estadísticas de las X$ se puede experimentar una degradación de los servicios, dado que se está accediendo de forma muy consistente a los datos en memoria, por eso si no se puede elegir un período de alto uso de recursos , se puede elegir un período inmediatamente posterior, con lo cual se puede recopilar información más acertada que un período de baja carga.

e) Como el hecho de tomar estadísticas puede conllevar inconvenientes de performance (por el instante en que se toman) , se recomienda que todo el proceso pueda ser monitoreado y llevado a cabo en ambiente de Testing.

f) El hecho de que no existan estadísticas para las tablas fixed puede ser incluso mejor que estadísticas erróneas, lo que hay que tener en cuenta que estadísticas bien tomadas pueden traer muchos beneficios para los planes de ejecución de las consultas que se ejecutan de forma interna.

g) Una vez que estas estadísticas son tomadas , no tienen que volver a generarse cuando la instancia se reinicia, Oracle las almacena en disco, sólo se debiesen tomar ante algún cambio de configuración de la instancia o a nivel de base de datos.



Respaldo de las estadísticas actuales

Antes de efectuar cualquier actividad sobre la base de datos como buena práctica se debe realizar un respaldo, para las estadísticas es lo mismo, por ende los pasos a seguir es respaldar las estadísticas actuales de las tablas Fixed y mantenerlas almacenadas , ya que puede formar parte del plan el hecho de revertir el proceso de recopilación de estadísticas, por algún mal plan de ejecución que pueda aparecer.

Para llevar a cabo esta actividad , se siguen los siguientes pasos :

a) Se crea una tabla para almacenar las estadísticas de las tablas Fixed, se indica el owner y el nombre que tendrá la tabla

SQL> exec dbms_stats.create_stat_table ('SYSTEM', 'table_stats_fixed');


b) Se chequean los segmentos generados

SQL> select owner , segment_name , segment_type from dba_segments
2 where segment_name like 'TABLE_STATS%';

OWNER SEGMENT_NAME SEGMENT_TYPE TABLESPACE_NAME
-------------------- ------------------------------ ------------------ ---------
SYSTEM TABLE_STATS_FIXED TABLE SYSTEM
SYSTEM TABLE_STATS_FIXED INDEX SYSTEM


c) Se deben mover los segmentos generados para que en ningún motivo queden en el tablespace SYSTEM.

SQL> alter table system.table_stats_fixed move tablespace users;

Table altered.

SQL> alter index system.table_stats_fixed rebuild tablespace users;

Index altered.


d) Se procede a exportar la metadata de las estadísticas y a dejarla en la tabla recientemente creada.

SQL> exec dbms_stats.export_fixed_objects_stats (statown=> 'SYSTEM', stattab => 'TABLE_STATS_FIXED');


e) Se chequea el funcionamiento global del sistema y si procede , se debe restaurar (importar) la anterior data, para ello ocupamos el siguiente código.

SQL> exec dbms_stats.import_fixed_objects_stats(statown=>'SYSTEM',stattab=>'TABLE_STATS_FIXED');


Espero les sirva y claro , desde ahora sepan incorporar dentro de sus planes de mantenimiento este tipo de procesos , tan importante para Oracle

by Ligarius
07.02.13. 07:40:03. 1259 words, 3076 views. Categories: Tuning / Performance ,

¿Qué es un INDEX SKIP SCAN?



Siempre hemos escuchado que el no ocupar la cabecera del índice hará que simplemente no ocupemos el índice (índices compuestos) ... pues bien esto se mantuvo por harto tiempo, hasta la versión 9i de Oracle.




Quizás es algo que quedo en la retina y que casi siempre forzábamos haciendo un típico "campo1 > 0" para que realmente ocupará el índice, pero eso es lo más malo y erróneo que podemos hacer... teniendo en cuenta que hacer un FULL sobre una tabla no es siempre malo.


Un INDEX SKIP SCAN permite usar sólo una parte del índice cuando no estamos utilizando su cabecera, esto es muy provechoso ya que de todas formas no estamos haciendo un FULL sobre la tabla, todo esto es analizado por el CBO , con lo cual "siempre" elige el mejor plan de ejecución, es más , CBO podría dejar fuera de acción la cabecera de un índice y solamente ocupar "su cuerpo". Esta opción solamente está disponible para índices del tipo B*Tree


Para graficar de mejor forma el comportamiento de un INDEX SKIP SCAN , va un ejemplo


- Creamos una tabla
create table at2(a varchar2(3),b varchar2(10),c varchar2(5));


- La cargamos de información

begin
  for i in 1..1000 loop
      insert into at2 values('M', i, 'M');
      insert into at2 values('F', i, 'F');
  end loop;
end;
/


- Creamos un índice sobre la tabla

create index at2_i on at2(a,b,c);


- Analizamos la tabla con el método "FOR ALL COLUMNS SIZE 1" que significa, tomar estadísticas básicas del objeto, sin necesidad de histogramas, datos estadísticos como mínimo, máximo ,cantidad de valores distintos, etc.

exec dbms_stats.gather_table_stats(OWNNAME => NULL, TABNAME => 'at2', 
 CASCADE => TRUE, method_opt => 'FOR ALL COLUMNS SIZE 1');


- Seteamos el trace de la consulta y ejecutamos la query , pero ocupando el segundo campo del índice

SQL- set autotrace on exp stat

SQL> select * from at2 where b='352';

A   B          C
--- ---------- -----
F   352        F
M   352        M


Execution Plan
----------------------------------------------------------
Plan hash value: 1279236776

--------------------------------------------------------------------------
| Id  | Operation        | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT |       |     2 |    16 |     3   (0)| 00:00:01 |
|*  1 |  INDEX SKIP SCAN | AT2_I |     2 |    16 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - access("B"='352')
       filter("B"='352')


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          7  consistent gets
          0  physical reads
          0  redo size
        728  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed


Ciertas cosas que mencionar...

- Aparece claramente en el plan de ejecución lo siguiente "INDEX SKIP SCAN" , pues está es la sentencia que buscábamos, pues el plan de ejecución indica que lo mejor es ocupar el índice AT2_I , a pesar de que ocupemos sólo el segundo campo .

- Hay que tener en cuenta la estadística el valor de "consistent gets" que en este caso es 8 y que representa la cantidad de veces que se obtiene información desde un bloque Oracle que se encuentra en memoria (Buffer Cache)


Ahora bien, si ejecutamos la misma consulta , pero le indicamos que no ocuparemos el índice, pues la cantidad de "consistents gets" sube, por ende no es lo óptimo.. y esto se desprende del FULL SCAN que está haciendo sobre la tabla.

SQL- select /*+ no_index (at2) */ * from at2 where b='352'

A   B          C
--- ---------- -----
M   352        M
F   352        F


Execution Plan
----------------------------------------------------------
Plan hash value: 2725892949

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |    16 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| AT2  |     2 |    16 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("B"='352')


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          8  consistent gets
          0  physical reads
          0  redo size
        728  bytes sent via SQL*Net to client
        524  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          2  rows processed



Referencias
[Metalink] : Index Skip Scan Feature [ID 212391.1]
Index Skip Scan Oracle 10g

Espero les sea de utilidad

by Ligarius
26.12.12. 06:17:36. 672 words, 6083 views. Categories: Tuning / Performance ,

<< 1 2 3 4 5 6 7 8 >>