Sie sind auf Seite 1von 9

Optimizer Hints

Preparado para
DGIC-SSEAF
Por Excelsis.
Setiembre, 2010

1
Contenidos

................................................................................................................................................1

Objetivos 3

Entendiendo los Optimizer Hints. 4

Especificando Hints 7

Verificación de Hints usados actualmente por el Ministerio de Hacienda. 9

2
Objetivos

Entender la utilización de los hints y las ventajas de hacerlo.


Conocer las mejores prácticas, los hints vigentes y los que ya no lo están.

3
Entendiendo los Optimizer Hints.

Los hints le permiten tomar decisiones que normalmente son hechas por el optimizador. Como el diseñador de su
aplicación, usted puede conocer información acerca de sus datos que el optimizador desconoce. Los hints proveen
mecanismos que pueden instruir al optimizador a elegir ciertos planes de ejecución basados en criterios específicos.
Por ejemplo, usted puede saber que cierto índice es más selectivo para ciertas consultas. Basado en ésta información
usted puede elegir un plan de ejecución mas efectivo que el optimizador. En ese caso, use los hints para instruir al
optimizador a usar el plan de ejecución más óptimo.

Los Hints pueden ser de los siguientes tipos generales:


Single-table: Son los hints especificados en una tabla o vista.
Multi-table: Son iguales a los hints de tipo Single-table con la diferencia de que pueden ser especificados en
multiples tablas o vistas.
Query block: Son hints que operan en simples bloques de consultas.
Statement: Son hints que operan en la consulta SQL completa.

Hints por categorías:


Hints for optimization Approaches and Goals (Hints para optimización de enfoques y objetivos)
Los siguiente hints le permiten elegir entre la optimización de enfoques y objetivos:
ALL_ROWS
FIRST_ROWS(N)
Si una sentencia SQL tiene un hint de éste tipo, entonces el optimzador utiliza el enfoque especificado sin
tener en cuenta la presencia o ausencia de estadísticas, el valor del parámetro de inicialización
OPTIMIZER_MODE y el de OPTIMIZER_MODE de la declaración del ALTER_SESSION.
Hints for Access Paths
Los siguientes hints permiten indicar al optimizador el camino de acceso a una tabla:
FULL
CLUSTER
HASH
INDEX
NO_INDEX
INDEX_ASC
INDEX_COMBINE
INDEX_JOIN
INDEX_DESC
INDEX_FFS
NO_INDEX_FFS
INDEX_SS
INDEX_SS_ASC
INDEX_SS_DESC
NO_INDEX_SS

4
Especificando alguno de los hints citados, indican al optimizador elegir un camino especifico sólo si dicho camino
está disponible, basado en la existencia de un indice o cluster y en la construcción sintactica de la sentencia SQL. Si
el hint especifica una ruta de acceso que no está disponible, el optimizador simplemente ignora dicho hint.

Hints for Query Transformations


Cada uno de los siguientes hints indican al optimizador a usar transformaciones especificas en sentencias
SQL:
NO_QUERY_TRANSFORMATION
USE_CONCAT
NO_EXPAND
REWRITE
NO_REWRITE
MERGE
NO_MERGE
STAR_TRANSFORMATION
NO_STAR_TRANSFORMATION
FACT
NO_FACT
UNNEST
NO_UNNEST

Hints for Joins Orders


LEADING
ORDERED
Hints for Joins Operations
Cada uno de los siguiente hints indican al optimizador a utilizar específicas operaciones de JOIN para una
tabla.
USE_NL
NO_USE_NL
USE_NL_WITH_INDEX
USE_MERGE
NO_USE_MERGE
USE_HASH
NO_USE_HASH
Hints for Parallel Executions
Los hints que siguen indican al optimizador a sobre como las declaraciones son paralelizadas o no cuando
se usan ejecuciones paralelas.
PARALLEL
PQ_DISTRIBUTE
PARALLEL_INDEX
NO_PARALLEL_INDEX

5
Aditional Hints

APPEND
NOAPPEND
CACHE
NOCACHE
PUSH_PRED
NO_PUSH_PRED
PUSH_SUBQ
NO_PUSH_SUBQ
QB_NAME
CURSOR_SHARING_EXACT
DRIVING_SITE
DYNAMIC_SAMPLING
MODEL_MIN_ANALYSIS

6
Especificando Hints

Los hints aplican sólo en la optimización del bloque de la declaración en donde ellos aparecen. Un bloque de
declaración es cualquiera de los siguientes declaraciones o parte de declaraciones:

- Una declaración select, update, delete


- Una consulta padre o subconsulta de una declaración compleja
- Parte de una consulta compuesta

Por ejemplo, un consulta compuesta de dos queries combinados por un opeador UNION, contiene dos bloques, uno
por cada query. Por ésta razón los hints en la primera consulta, sólo trabajarán en la optimización de ésta, no siendo
así para el segundo bloque.

Especificando un full set de Hints:


Cuando se usan hints, en algunos casos, usted puede que necesite especificar un full set de hints para
asegurarse de la optima ejecucion del plan. Por ejemplo, si usted tiene una consulta muy compleja que
consta de varias tablas con joins y ha especificado solamente el hint INDEX para una tabla determinada,
entonces el optimizador necesita determinar las restantes rutas de acceso a ser usadas, como también el
método join correspondiente. Por lo tanto, por que se haya específicado el hint, el optimizador podría no
usar dicho índice por la combinación de las rutas de acceso y los métodos de join seleccionados.
En el ejemplo, el hint LEADING, especifica el orden exacto del join a ser usado, así como también los
metodos de join a usarse en diferentes tablas.
SELECT /*+ LEADING(e2 e1) USE_NL(e1) INDEX(e1 emp_emp_id_pk) USE_MERGE(j) FULL(j) */
e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal
FROM employees e1, employees e2, job_history j
WHERE e1.employee_id = e2.manager_id
AND e1.employee_id = j.employee_id
AND e1.hire_date = j.start_date
GROUP BY e1.first_name, e1.last_name, j.job_id
ORDER BY total_sal;

Especificando un Query Block en un hint:


Para especificar un query block en una consulta, un nombre opcional para dicho query block puede
ser usado en un hint para especificarle el query block al cual el hint debe aplicar.
La sintaxis del argumento del query block es @queryblock donde queryblock es el identificador que
especifica el query block en la consulta. El identificador puede ser generado por el sistema o bien
puede ser especificado por el usuario.
El identificador generado por el sistema puede ser obtenido usando el EXPLAIN PLAN para la
consulta
El identificador especificado por el usuario puede ser seteado con el hint QB_NAME.
Ejemplo: El query block name es usado con el hint NO_UNNEST para especificar un query block
en una declaración SELECT:
CREATE OR REPLACE VIEW v AS
SELECT e1.first_name, e1.last_name, j.job_id, sum(e2.salary) total_sal
FROM employees e1,( SELECT * FROM employees e3) e2, job_history j WHERE
e1.employee_id = e2.manager_id
AND e1.employee_id = j.employee_id
AND e1.hire_date = j.start_date
AND e1.salary = ( SELECT max(e2.salary)
FROM employees e2

7
WHERE e2.department_id =
e1.department_id )
GROUP BY e1.first_name, e1.last_name, j.job_id
ORDER BY total_sal;

Luego de correr el EXPLAIN PLAN para la consulta, en el plan table output, se puede determinar el
identificador del para el query block generado por el sistema.

Por ejemplo, el nombre del query block es mostrado en el siguiente plan table output:

Query Block Name / Object Alias (identified by operation id):

-------------------------------------------------------------
...
10 - SEL$4 / E2@SEL$4

Luego de determinar el nombre del query block, el mismo puede ser usado en la siguiente consulta SQL:

SELECT /*+ NO_UNNEST( @SEL$4 ) */

*
FROM v;

8
Verificación de Hints usados actualmente por el
Ministerio de Hacienda.

En base a los resultados de los scripts de búsqueda de los hints, los que están implementados en las declaraciones
SQL de sus sistemas que pudimos encontrar son los siguientes:

INDEX: Indica al optimizador a utilizar un índice especifico para la búsqueda en una tabla. Éste hint puede ser
utilizado para los tipos de índices: function-based, domain, B-tree, bitmap y bitmap join.
SELECT /*+ INDEX (employees emp_department_ix)*/
employee_id, department_id
FROM employees
WHERE department_id > 50;

ORDERED: Indica a Oracle a realizar el join de las tablas en el orden en que aparecen en la cláusula FROM.
Cuando se omite el hint ORDERED desde una sentencia SQL que necesita join, el optimizador elige el
orden en el join de las tablas.
SELECT /*+ORDERED */ o.order_id, c.customer_id, l.unit_price * l.quantity
FROM customers c, order_items l, orders o
WHERE c.cust_last_name = :b1
AND o.customer_id = c.customer_id
AND o.order_id = l.order_id;

INDEX_FFS: Indica al optimizador a realizar un fast full index en vez de un full table scan.
SELECT /*+ INDEX_FFS(e emp_name_ix) */ first_name
FROM employees e;

USE_HASH: Indica al optimizador a realizar un join de una tabla con otra usando HASH_JOIN.
SELECT /*+ USE_HASH(l h) */ *
FROM orders h, order_items l
WHERE l.order_id = h.order_id
AND l.order_id > 3500;

USE_HASH_SJ: Insertado dentro de una subquery de tipo EXISTS; convierte la subquery en un tipo especial de
hash join entre la tabla1 y tabla2 que preserva la semantica de la subquery. Es decir, incluso si hay más de una fila
coincidente en tabla2 de una fila en tabla1, la fila en tabla1 se devuelve sólo una vez.
Recomendación: El uso de los Hints citados arriba mantienen su uso y definición para la versión 10g de la
base datos, siguiendo la misma sintaxis e implementación que en la versión 9i.