Está en la página 1de 28

CONTENIDO

1 INTRODUCCIN .......................................................................................................................................3 1.1 1.2 2 2.1 2.2 2.3 2.4 2.5 3 3.1 3.2 3.3 3.4 3.5 4 PROPSITO DEL DOCUMENTO................................................................................................................3 INTRODUCCIN AL STRUCTURED QUERY LANGUAGE ..........................................................................3 COMPONENTES DEL SQL .......................................................................................................................4 CONSULTAS DE SELECCIN ..................................................................................................................4 CRITERIOS DE SELECCIN .....................................................................................................................6 AGRUPAMIENTO DE REGISTROS Y FUNCIONES AGREGADAS ................................................................ 7 CONSULTAS DE MANIPULACIN DE DATOS ...........................................................................................9 CONSULTAS DE COMBINACIN ENTRE TABLAS ................................................................................... 11 INNERS JOINS .......................................................................................................................................12 OUTER JOINS ........................................................................................................................................14 CONSULTAS DE AUTOCOMBINACIN ..................................................................................................15 CONSULTAS DE COMBINACIONES NO COMUNES ................................................................................. 16

REVISIN DE CONCEPTOS BSICOS DE SQL .................................................................................4

CONSULTAS DE UNIN INTERNAS (JOINS) ...................................................................................11

CONSULTAS DE UNIN EXTERNAS (UNIONS) ..............................................................................17


P?gina de 52

SUBCONSULTAS .....................................................................................................................................19 5.1 5.2 5.3 EMPLEO DE SUBCONSULTAS................................................................................................................19 GRUPOS CON SUBCONSULTAS..............................................................................................................21 CASOS PRCTICOS ...............................................................................................................................22 CONSEJOS GENERALES.........................................................................................................................23 EMPLEO DE NDICES .............................................................................................................................25 SENTENCIAS CON JOINS. ......................................................................................................................31 SENTENCIAS CON SUBCONSULTAS.......................................................................................................32 VISTAS ................................................................................................................................................. 33 GENERALIDADES PARA LA OPTIMIZACIN DE SENTENCIAS SQL ........................................................ 34 TIPOS DE TABLAS ................................................................................................................................36 INDICES, TIPOS DE NDICES..................................................................................................................42 PLAN DE EJECUCIN: INTERPRETACIN DE RESULTADOS................................................................... 44 UTILIDADES DE INFORMACIN ESTADSTICA SOBRE LA EJECUCIN DE SENTENCIAS ......................... 45 ESTADSTICAS ......................................................................................................................................47

OPTIMIZACIN DE CONSULTAS ......................................................................................................23 6.1 6.2 6.3 6.4 6.5

OPTIMIZACIN ORACLE: DATABASE TUNING ...........................................................................34 7.1 7.2 7.3 7.4 7.5 7.6

8 9

DICCIONARIO DE DATOS ORACLE..................................................................................................48 DICCIONARIO DE DATOS SQL SERVER .........................................................................................51

Optimizacin de consultas

El lenguaje SQL es no procedimental, es decir, en las sentencias se indica que queremos conseguir y no como lo tiene que hacer el interprete para conseguirlo. Esto es slo teora, pues en la prctica a todos los gestores de SQL hay que especificar sus propias reglas para optimizar el rendimiento. Por tanto, muchas veces no basta con especificar una sentencia SQL correcta, sino que adems, hay que indicarle como tiene que hacerlo si queremos que el tiempo de respuesta sea el mnimo. En este apartado veremos como mejorar el tiempo de respuesta de nuestro interprete ante unas determinadas situaciones:

6.1

Consejos generales

La construccin de una sentencia y los operadores y condiciones empleados determinan como la interpreta el analizador y por tanto su plan de ejecucin. En muchos casos, la reescritura de una sentencia puede cambiar radicalmente su plan de ejecucin y su rendimiento en el sistema. Como norma ms general, una sentencia est optimizada cuando implica realizar el nmero ms pequeo posible de accesos a los datos. 9 Hay que procurar que las condiciones de la clusula WHERE sean lo ms restringidas posibles; debemos evitar accesos a filas innecesarias. 9 Hay que especificar siempre las columnas a las que queremos acceder (No hacer nunca SELECT *...) evitando as recuperar columnas que luego no utilizaremos y por qu el gestor debe leer primero la estructura de la tabla antes de ejecutar la sentencia. En la medida de lo posible hay que evitar que las sentencias SQL estn embebidas dentro del cdigo de la aplicacin. Es mucho ms eficaz usar vistas o procedimientos almacenados por que el gestor los guarda compilados. Si se trata de una sentencia embebida el gestor debe compilarla antes de ejecutarla. Tip: Si utilizamos varias tablas en la consulta, especificar siempre a que tabla pertenece cada campo, le ahorraremos al gestor el tiempo de localizar a que tabla pertenece el campo. En lugar de: SELECT Nombre, Factura FROM Clientes, Facturacion WHERE IdCliente = IdClienteFacturado Usar : SELECT Clientes.Nombre, Facturacion.Factura WHERE Clientes.IdCliente = Facturacion.IdClienteFacturado.

6.1.1

Diseo de las tablas


P?gina de 52

La optimizacin pasa por un correcto diseo del modelo de datos (Tablas), se deben seguir los siguientes consejos:

9 Normalizar las tablas, al menos hasta la tercera forma normal, para asegurar que no hay duplicidad de datos y se aprovecha al mximo el almacenamiento en las tablas. Si hay que desnormalizar alguna tabla pensar en la ocupacin y en el rendimiento antes de proceder. 9 Los primeros campos de cada tabla deben ser aquellos campos requeridos y dentro de los requeridos primero se definen los de longitud fija y despus los de longitud variable. 9 Ajustar al mximo el tamao de los campos para no desperdiciar espacio. 9 Es muy habitual dejar un campo de texto para observaciones en las tablas. Si este campo se va a utilizar con poca frecuencia o si se ha definido con gran tamao, por si acaso, es mejor crear una nueva tabla que contenga la clave primaria de la primera y el campo para observaciones.

6.1.2

Campos de Filtro

Se procurar elegir en la clusula WHERE aquellos campos que formen parte de la clave de la tabla por el cual interrogamos. Adems se especificarn en el mismo orden en el que estn definidos en la clave. Tip: Interrogar siempre por campos que sean clave. Si deseamos interrogar por campos pertenecientes a ndices compuestos es mejor utilizar todos los campos de todos los ndices. Supongamos que tenemos un ndice formado por el campo NOMBRE y el campo APELLIDO y otro ndice formado por el campo EDAD. La sentencia WHERE NOMBRE='Juan' AND APELLIDO Like '%' AND EDAD = 20 sera ms optima que WHERE NOMBRE = 'Juan' AND EDAD = 20 por que el gestor, en este segundo caso, no puede usar el primer ndice y ambas sentencias son equivalentes porque la condicin APELLIDO Like '%' devolvera todos los registros.

6.1.3 Valores NULL


Con los valores Null debemos tener en cuenta las siguientes premisas: Un valor NULL es un valor desconocido Un Null no implica un cero o un espacio en blanco; es un valor que significa informacin no disponible Is Null debe ser utilizado para determinar valores Null contenidos en una columna; la sintaxis = Null es vlida pero no recomendada Un valor Null nunca es igual a otro valor Null

Los valores Null se consideran en el ordenamiento y en los grupos, Algunas columnas son definidas para permitir valores NULL Si un elemento es Null en una operacin el resultado ser Null

6.2

Empleo de ndices

Los ndices son campos elegidos arbitrariamente por el constructor de la base de datos que permiten la bsqueda a partir de dicho campo a una velocidad notablemente superior. Sin embargo, esta ventaja se ve contrarrestada por el hecho de ocupar mucha ms memoria (el doble ms o menos) y de requerir para su insercin y actualizacin un tiempo de proceso superior. Un caso en el que los ndices pueden resultar muy tiles es cuando realizamos peticiones simultneas sobre varias tablas. En este caso, el proceso de seleccin puede acelerarse sensiblemente si indexamos los campos que sirven de nexo entre las dos tablas. Los ndices pueden resultar contraproducentes si los introducimos sobre campos triviales a partir de los cuales no se realiza ningn tipo de peticin ya que, adems del problema de memoria ya mencionado, estamos ralentizando otras tareas de la base de datos como son la edicin, insercin y borrado. Es por ello que vale la pena pensrselo dos veces antes de indexar un campo que no sirve de criterio para bsquedas o que es usado con muy poca frecuencia por razones de mantenimiento. La mayora de consultas se optimizan si acceden a travs de un ndice. Ante una sentencia que no realice un acceso por ndice y que consideremos ineficiente se ha de considerar el introducir un ndice en la base, y si ste ya existe, averiguar porqu no lo utiliza y reescribir la sentencia para que lo haga. En relacin a todo esto, hay que tener en cuenta las siguientes consideraciones: Utilizar ndice para consultas muy restrictivas. El volumen mximo de datos recuperados sera del orden del 15 20 % de los registros de la tabla. Para esto hay que conocer siempre el volumen (no es igual el 20 % de una tabla de 1M registros que de una tabla de 20M registros) , naturaleza y distribucin de los datos a tratar (una sentencia que funciona bien con algunos valores puede ser inadmisible si hay un valor muy mayoritario), sin olvidar las previsiones de crecimiento; en este sentido, la informacin de una base de desarrollo puede ser totalmente errnea, la aplicacin se tiene que ajustar con una carga de datos realista. Referenciar la columna o columnas del ndice en la clusula WHERE. El analizador no utilizar ndice en caso contrario. Se debe tratar que los ndice tengan la mayor selectividad posible (es decir el nmero de filas obtenido por cada valor del clave del ndice). A mayor selectividad del ndice mayor probabilidad de que sea usado por el optimizador de consultas. Se deben usar los ndices con moderacin, es decir, unos pocos ndices pueden ser tiles pero demasiados ndices pueden afectar negativamente al rendimiento porque hay que mantenerlos actualizados cada vez que se realizan operacin de insercin, actualizacin y borrado en los datos.
P?gina de 52

No poner ndices en tablas pequeas. No podemos indexar todos los campos de una tabla extensa ya que doblaramos el tamao de la base de datos. Igualmente. Utilizar el menor nmero posible de columnas en el ndice (ndices estrechos), ya que estos ocupan menos espacio y necesitan menos sobrecarga de mantenimiento. Las referencias de las columnas de un ndice compuesto en la clusula WHERE tienen que estar en el mismo orden que en el ndice. No es obligatorio incluir condiciones sobre todas, pero s sobre la primera, y si hay ms condiciones deberan ir sobre las siguientes columnas en el orden del ndice. Lo ilustraremos con un ejemplo: (ndice: NUM_CLIENTE, NOMBRE_CLIENTE, FECHA_ENTRADA) El Analizador utilizar el ndice con una clusula WHERE de la forma: NUM_CLIENTE = valor AND NOMBRE_CLIENTE = valor AND FECHA_ENTRADA = valor la siguiente: NUM_CLIENTE = valor AND NOMBRE_CLIENTE = valor la siguiente: NUM_CLIENTE = valor la siguiente: NUM_CLIENTE = valor AND FECHA_ENTRADA = valor En cambio NO utilizar el ndice si el WHERE contiene: NOMBRE_CLIENTE = valor AND FECHA_ENTRADA = valor Tampoco utilizar cuando: NOMBRE_CLIENTE = valor

No modificar la columna del ndice en el WHERE con funciones o expresiones. Esto deshabilita el uso del ndice. Por ejemplo, no se usaran ndice condiciones en el WHERE de la forma: SUBSTR(NOMBRE, 1, 5) = ... CLIENTE||'_01' = ... TO_CHAR(FECHA_ENTRADA, 'DD/MM/YYYY')=...;

Notar que podemos encontrar casos tan sencillos como los siguientes: (ndice 1: SUELDO ; ndice 2: NOMBRE) SELECT SUELDO FROM EMPLEADOS WHERE SUELDO*12 > 1500000; SELECT NOMBRE FROM CLIENTES WHERE SUBSTR(NOMBRE,1,1) = 'A'; Que no utilizan ndice, pero en cambio s que lo hacen: SELECT SUELDO FROM EMPLEADOS WHERE SUELDO > 1500000/12; SELECT NOMBRE FROM CLIENTES WHERE NOMBRE LIKE = 'A%'; En relacin con esto, hay que tener en cuenta que las conversiones automticas que realiza Oracle al comparar datos de tipos diferentes entran dentro de esta categora y por tanto inhabilitan el uso del ndice. De aqu: Si hay que hacer conversiones de tipos en la clusula WHERE, las haremos nosotros explcitamente con las funciones al efecto como TO_CHAR, TO_DATE, etc., y si es posible, siempre sobre datos fijos, no sobre columnas. No utilizar el operador LIKE con un valor cuyo primer carcter sea el comodn '%'; ya que esto obliga a acceder a toda la tabla. En cambio, S que se utilizar ndice si la cadena empieza por un carcter fijo. Ejemplo: (ndice: NOMBRE_CLIENTE) NOMBRE_CLIENTE LIKE '%AA...' => Acceso a toda la tabla. NOMBRE_CLIENTE LIKE 'AA%' => Acceso por ndice. Tip: No utilizar LIKE con columnas que no sean de tipo carcter. En este caso, Oracle realiza implcitamente una conversin de tipo, por tanto, nunca se utilizar ndice.

Si en algn caso, queremos obligar al optimizador a realizar un acceso a toda la tabla a pesar de que en la condicin del WHERE se referencie a una columna indexada (Es el caso de tablas muy pequeas o con un ndice poco restrictivo), podemos utilizar una tcnica tan sencilla como:

P?gina de 52

Para una columna de tipo carcter: NOMBRE || '' =... Para una columna de tipo numrico: TOTAL + 0 = ... Tip: La optimizacin basada en costos de Oracle (Default) ya realiza esta operacin Evitar los operadores NOT EQUAL (!=) ya que siempre acceden a toda la tabla al presuponer el analizador que se va a acceder a la mayora de los registros. As: (ndice: ZONA) SELECT CLIENTE FROM CLIENTES WHERE ZONA != 5; no utiliza el ndice, pero s que lo har: SELECT CLIENTE FROM CLIENTES WHERE ZONA > 5 AND ZONA < 5; No hay problema en utilizar las otras condiciones NOT, como por ejemplo: SELECT CLIENTE FROM CLIENTES WHERE NOT ZONA > 5; Donde la condicin: NOT ZONA > 5 se transformar en ZONA =< 5 y utilizar el ndice sobre ZONA de antes.

Para acceder va ndice con la clusula ORDER BY hay que atender a las mismas consideraciones que las hechas para WHERE: La columna del ndice no puede estar modificada por una expresin o funcin. Las columnas de un ndice compuesto han de estar en el mismo orden que en el ndice, siendo vlidas tambin las otras restricciones hechas para el caso de WHERE. Si la(s) columna(s) de la clusula ORDER BY no estn indexadas o no se puede utilizar el ndice, se realiza un 'Sort' de la tabla (o de las filas devueltas por la clusula WHERE).

Se puede utilizar un acceso por ndice con las funciones MAX y MIN en consultas simples (no Joins) si: No hay clusula WHERE o GROUP BY MAX o MIN son la nica expresin en la consulta. Se refieren a una sola columna, sin ms operadores.

Por ejemplo: (ndice IMPORTE) SELECT MAX(IMPORTE) FROM FACTURAS; SELECT MAX(IMPORTE)*2 FROM FACTURAS; Utilizan ndice, en cambio, no lo hacen: SELECT MAX(IMPORTE) FROM FACTURAS WHERE ID_CLI = 15; SELECT MAX(IMPORTE*2) FROM FACTURAS;

Condiciones ligadas mediante OR. El analizador de Oracle interpreta una clusula WHERE con n condiciones unidas con OR como n consultas independientes, cada una con una condicin, realizando una concentracin al final. Si queremos tener accesos por ndice en este caso, ser necesario que cada condicin referencie a una columna indexada. Tambin se transforma en N consultas independientes una condicin con el operador: IN ( Conjunto de valores ), y por tanto se utilizar un ndice si la columna de la condicin est indexada.

Evitar siempre que sea posible las funciones de grupo: DISTINCT, GROUP BY. Nunca utilizan ndice y realizan siempre una ordenacin (Sort) de la tabla: Las operaciones de Sort son unas de las que ms cargan el servidor, especialmente si tiene que recurrir al tablespace temporal al llenarse la SORT_AREA de la SGA, ya que entonces hay I/O extra sobre el disco. Se pueden substituir por una Join aunque ello puede complicar mucho la consulta (hasta hacerla ineficiente) o no ser posible. En todo caso, siempre hay que incluir una clusula WHERE previa que restrinja lo ms posible las filas a ordenar y que s que utilizar un ndice para ello si es posible. Por esta razn, es preferible GROUP BY frente a DISTINCT. Con GROUP BY utilizar siempre que sea posible WHERE en lugar de HAVING para introducir la condicin. As la sentencia: SELECT ZONA, SUM(FACTURACION) FROM CLIENTES WHERE ZONA = 5 GROUP BY ZONA; utilizar un ndice sobre ZONA (si existe), pero la sentencia: SELECT ZONA, SUM(FACTURACION) FROM CLIENTES GROUP BY ZONA

P?gina de 52

HAVING ZONA = 5; agrupar todos los registros descartando luego los que no tengan ZONA = 5, sin utilizar el ndice No obstante, existen casos en que la presencia de la columna no garantiza el uso de su ndice, ya que stos son ignorados, como en las siguientes situaciones cuando la columna indexada es: Evaluada con el uso de los operadores IS NULL o IS NOT NULL. SELECT nombre,articulo,valor FROM clientes,ventas WHERE nombre IS NOT NULL; Modificada por alguna funcin, excepto por las funciones MAX(columna) o MIN(columna). SELECT nombre,articulo,valor FROM clientes,ventas WHERE UPPER(nombre)>' '; Usada en una comparacin con el operador LIKE a un patrn de consulta que comienza con alguno de los signos especiales (% _). SELECT nombre,articulo,valor FROM clientes,ventas WHERE nombre LIKE '%DEPORTE%'; Finalmente debemos aclarar que los registros cuyo valor es NULL para la columna indexada, no forman parte del ndice. Por lo tanto, cuando el ndice se activa estos registros no se muestran como resultado de la consulta.

6.3

Sentencias con Joins.

Una Join es una consulta que combina filas de dos o ms tablas. El analizador realizar una Join siempre que encuentre ms de una tabla en la clusula FROM. Para ello decide que camino de acceso a los datos se ha de seguir (siendo vlidas las consideraciones anteriores sobre el acceso a las tablas por ndice) y el algoritmo de Join a emplear. Para el uso de Joins, aparte de lo dicho antes para ndices, hemos de considerar lo siguiente: 9 En general, es preferible utilizar, si es posible, UNION (mejor UNION ALL si da el resultado buscado, ya que no realiza 'sort' sobre las tablas, mientras que UNION s), en lugar de accesos con Join, al menos con tablas de volmenes parecidos. 9 Hay que tener en cuenta la relacin entre la tabla conductora y la secundaria: 1 a n (dem m a n) 1 a 1 (dem n a 1). En el primer caso, accederemos a n filas de la tabla secundaria por cada una de la conductora, mientras que en el segundo slo se recuperar una fila de la tabla secundaria por fila de la conductora. Siempre es preferible este segundo caso, y se ha de intentar obtenerlo mediante funciones de agrupacin o eliminacin de duplicados, si es posible obtener el mismo resultado. 9 Si realizamos una Join entre una vista y una tabla, la vista ha de actuar como conductora. 9 No es recomendable realizar una Join entre vistas, sobre todo si podemos hacerla sobre las tablas. 9 Algunas consideraciones sobre el uso de Hints en Joins: o o Si la tabla conductora es mucho ms pequea que la secundaria, es preferible hacer un NL Join. Si es la tabla secundaria la que es mucho ms pequea que la conductora, montaremos un Hash Join sobre la pequea. En principio, si el volumen de las tablas es parecido, tambin es preferible usar un Hash sobre la tabla secundaria. Siempre que se use un Hash Join hay que tener en cuenta las columnas seleccionadas, ya que todas ellas formarn parte de la tabla Hash. Hay que intentar que sta sea lo ms pequea posible para reducir el trabajo sobre temporal. Con dos tablas pequeas podemos utilizar un Sort-Merge Join.

P?gina de 52

6.4

Sentencias con subconsultas

Una subconsulta es una sentencia SELECT (consulta interna) que proporciona el valor de una condicin en el WHERE de otra consulta (consulta principal). Internamente, el analizador transforma una subconsulta en una Join as que, en principio, suele ser ms efectivo utilizar una Join en lugar de una subconsulta, pero el uso de stas clarifica mucho la estructura de la sentencia. 9 Los operadores MINUS, UNION y INTERSECT no utilizan nunca ndices, realizan una ordenacin sobre los datos y optimizan las dos consultas por separado. 9 Los operadores NOT IN y NOT EXISTS siempre realizan un Full Scan de la tabla de la subconsulta, es ms efectivo utilizar un Outer Join (Producto externo), o bien una subconsulta con MINUS, UNION o INTERSECT. 9 En general, es mejor utilizar una Join que los operadores IN o EXISTS. 9 En optimizacin por reglas, el analizador reescribe la sentencia en un formato ms general. Con subconsultas, las normas generales seran: o Subconsultas no correlacionadas: Aquellas en que las tablas y condiciones de cada consulta son independientes. Como, por ejemplo: SELECT CLIENTE, ID_CLI FROM CLIENTES WHERE ID_CLI IN (SELECT ID_CLI FROM FACTURAS WHERE MES = 'ENERO') (Clientes que han facturado en el mes de Enero) Este tipo de subconsultas se transforman en una Join donde la tabla conductora es la de la consulta interna. Slo son convenientes si la consulta interna es muy restrictiva. o Subconsultas correlacionadas: Aquellas donde la consulta interna incorpora en el WHERE valores de la tabla de la consulta principal. Ejemplo (reescritura del ejemplo anterior): ELECT CLIENTE, ID_CLI FROM CLIENTES WHERE ID_CLI EXISTS (SELECT ID_CLI FROM FACTURAS WHERE FACTURAS.ID_CLI = CLIENTES.ID_CLI AND MES = 'ENERO') Este tipo de subconsultas de transforman en una Join donde la tabla conductora es la de la consulta principal que utilizar ndices si es posible. Slo son convenientes si la consulta principal es muy restrictiva. 9 A pesar de lo dicho, no hay que descartar las subconsultas; en algunos casos, MINUS, UNION o INTERSECT resultan ser la mejor optimizacin.

6.5

Vistas

Una vista es una tabla virtual que est definida por una consulta que consiste en una instruccin SELECT. Esta tabla virtual est creada con datos de una o ms tablas reales y, para los usuarios, una vista parece una tabla real. De hecho, una vista puede ser tratada del mismo modo que una tabla normal. En realidad, una vista se almacena simplemente como una instruccin SQL previamente definida. Cuando se accede a la vista, el DBMS une la instruccin SQL que se ejecuta en ese momento con la consulta que se use para definir la vista. Se pueden crear varios tipos de vistas, cada uno de los cuales tienen ventajas en ciertas situaciones. El tipo de vista que se ha de crear depende completamente de para qu se quiera usar la vista. Se pueden crear vistas de cualquiera de las siguientes maneras: 9 9 9 9 Subconjunto de columnas de una tabla Subconjunto de filas de una tabla Unin de dos o ms tablas Informacin de agregacin

Ventajas de las vistas 9 La ventaja de utilizar vistas es que se pueden crear vistas que tienen atributos diferentes sin tener que duplicar los datos. Siempre ofrecen los datos actualizados. La instruccin SELECT que define una vista slo se ejecuta cuando se accede a la vista, por tanto, todos los cambios de la tabla subyacente se reflejan en la vista. Puede tener un nivel diferente de seguridad del que posea la tabla subyacente. La consulta que define la vista se ejecuta con el nivel de seguridad que posea el usuario que crea la vista. De esta manera, se puede crear una vista que enmascare los datos que no se quieran mostrar a ciertas clases de usuarios.

P?gina de 52

7 7.1

Optimizacin ORACLE: Database Tuning Optimizacin de sentencias SQL

El objetivo de la optimizacin de las sentencias SQL presentes en las aplicaciones es doble; por un lado reducir el tiempo de respuesta de los usuarios y por otro reducir los recursos utilizados por el sistema para ejecutar las sentencias. Es preciso identificar aquellas sentencias SQL que consumen la mayor parte de los recursos del sistema y que ralentizan los tiempos de respuesta. Oracle nos proporciona la utilidad SQL_TRACE que combinada con la utilidad TKPROF, nos van a permitir determinar cuales de las sentencias de nuestra aplicacin son ineficientes. Los resultados de salida de las utilidades mencionadas deben ser analizados para tomar las medidas necesarias que mejoren el rendimiento. Sin embargo, independientemente de los resultados obtenidos podemos tener en cuenta los siguientes criterios generales. En las sentencias que se utilice ms de una tabla, realizar los equijoins de las mismas con = y con el operador AND. Evitar el uso de funciones SQL en la clusula WHERE. Cualquier expresin que utilice una funcin provoca que el optimizador no utilice el ndice correspondiente. Ejemplo: supongamos un ndice definido sobre el campo1 de la tabla a WHERE a.campo1 = b.campo2 en este caso el optimizador utilizara el ndice al ejecutar la sentencia. Sin embargo en el caso de utilizar una funcin WHERE b.campo2 = SUBSTR(a.campo1,1,4) el optimizador no utilizara el ndice lo que redundara en una prdida de eficiencia. Prestar atencin a las conversiones implcitas de datos. Si queremos usar el ndice definido sobre la columna colvchar de tipo VARCHAR2 Colvchar = <num_expr> y <num_expr> es de tipo NUMBER, la sentencia se trasforma en la siguiente TO_NUMBER(colvchar) = <num_expr> y al aplicarse la funcin de conversin el optimizador no utilizara el ndice. Simplificar querys complejas con el operador UNION. Evitar uso de IN y EXITS. En caso de ser necesario su uso, es preferible el IN en aquellos casos en que la sentencia principal recupere un gran nmero de filas; en caso contrario, es decir, cuando es la subconsulta la que presenta una alta cardinalidad es ms eficiente el uso de EXITS. Ejemplo:

La tabla clientes tiene 27.000 filas.

P?gina de 52

La tabla pedidos tiene 10.000 filas.

La SELECT selecciona los pedidos realizados por el cliente 1000. SELECT c.cliente_no, c.cliente_nombre FROM clientes c WHERE EXISTS (SELECT 1 FROM pedidos p WHERE c.cliente_no = p.cliente_no AND p.cliente_no = 1000)

El plan de ejecucin de la sentencia, recupera los 27.000 registros de la tabla clientes y los filtra con la tabla pedidos, lo que hace que la ejecucin sea ineficiente. Rescribiendo la sentencia con IN: SELECT c.cliente_no, c.cliente_nombre FROM clientes c WHERE c.cliente_no IN (SELECT p.cliente_no FROM pedidos p WHERE p.cliente_no = 1000)

El plan de ejecucin de la sentencia, recupera los pedidos del cliente 1000 para realizar posteriormente el join con la tabla clientes, lo que redunda en un mejor rendimiento de la sentencia. No usar ndices de manera generalizada. Los ndices suelen mejorar el rendimiento de las sentencias de consulta, pero ralentizan las operaciones de insercin, borrado y actualizacin. Tip: En las cargas masivas de datos deshabilitar constraints y triggers.

7.2.2

Tablas Temporales

Adems de las tablas estandar, Oracle permite la creacin de tablas temporales (temporary tables) que mantienen los datos nicamente durante la sesin o la transaccin en curso. El uso de estas tablas aumneta de manera considerable el rendimiento ya que los datos permanecen nicamente durante la sesin. Existen dos tipos de tablas temporales: 9 GLOBAL TEMPORARY: el contenido de la tabla es accesible desde cualquier sesin. 9 TEMPORARY: el contenido de la tabla slo es visible para la sesin en curso. Ejemplo: Tabla temporal que mantiene las filas (PRESERVE ROWS) una vez que la transaccin ha finalizado. CREATE GLOBAL TEMPORARY TABLE prueba_temp. (campo1 NUMBER)

ON COMMIT PRESERVE ROWS;

Ejemplo: Tabla temporal que elimina las filas (DELETE ROWS) una vez que la transaccin ha finalizado. CREATE GLOBAL TEMPORARY TABLE prueba_temp. (campo1 NUMBER)

ON COMMIT DELETE ROWS;

P?gina de 52

7.4

Plan de Ejecucin: Interpretacin de resultados

Oracle generalmente aplica una optimizacin basada es costes, que es una estrategia que consiste en la elaboracin de mltiples planes de ejecucin de una sentencia, eligindose aquella de menor coste de ejecucin. EXPLAIN PLAN muestra el plan de ejecucin elegido por el Optimizador de Oracle para ejecutar las sentencias SELECT, INSERT, UPDATE y DELETE. El plan de ejecucin es la secuencia ordenada de operaciones que Oracle realiza para ejecutar la sentencia correspondiente. 9 El resultado de EXPLAIN PLAN es un rbol que muestra la siguiente informacin: 9 Las tablas referenciadas en la sentencia SQL. 9 Los mtodos de acceso empleados para cada una de las tablas. 9 Los mtodos de unin (join) de las tablas. 9 Las operaciones realizadas sobre los datos: filtros, ordenaciones, acumulaciones. EXPLAIN PLAN utiliza la tabla PLAN_TABLE para almacenar los resultados del plan de ejecucin. Para crear dicha tabla en nuestro esquema ser necesario ejecutar el script UTLXPLAN.SQL almacenado por lo general en el path $ORACLE_HOME/rdbms/admin..

Ejecucin de EXPLAIN PLAN A cada una de las sentencias analizadas le asignamos un identificador diferente, para poder consultar el plan de ejecucin de cada una de ellas de manera individual. EXPLAIN PLAN SET STATEMENT_ID = <identificador_sentencia> FOR <sentencia SQL> Revisin de resultados de EXPLAIN PLAN Los campos de la tabla PLAN_TABLE ms significativos son los siguientes: Columna Descripcin Valor del identificador especificado en EXPLAIN PLAN Fecha y hora de ejecucin Operacin ejecutada, contiene los siguientes valores:

STATEMENT_ID TIMESTAMP OPERATION

SELECT STATEMENTINSERT STATEMENTUPDATE STATEMENTDELETE STATEMENT

OPTIONS

Descripcin de la operacin Nombre de la tabla analizada Nmero de bytes accedidos en la ejecucin de la sentencia (Optimizador Basado en Costes)

OBJECT_NAME BYTES

COST CARDINALITY

Coste estimado de la sentencia (Optimizador Basado en Costes) Nmero de filas accedidas en la ejecucin de la sentencia (Optimizador Basado en Costes)

Los valores ms usuales de OPERATION y OPTIONS son los siguientes: OPERATION INDEX OPTION Descripcin

RANGE SCAN Devuelve uno o ms ROWID de un ndice

MERGE JOIN Operacin que acepta dos conjuntos de filas, ordenado cada uno por un valor especfico; combina las filas de uno con las del otro y devuelve el resultado. NESTED LOOPS Operacin sobre dos conjuntos de registros. Compara cada fila de un conjunto con la del otro, devolviendo las filas que cumplen la condicin. TABLE ACCESS FULL Recupera todos los registros de la tabla Recupera los registros por el ndice en tablas no particionadas Recupera los registros por el ndice global en tablas particionadas Recupera los registros por el ndice local en tablas particionadas.

BY INDEX ROWID

BY GLOBAL INDEX ROWID BY LOCAL INDEX ROWID

7.5 7.5.1

Utilidades de informacin estadstica sobre la ejecucin de sentencias SQL_Trace

SQL_TRACE proporciona informacin estadstica sobre la ejecucin de sentencias SQL. Genera para cada una de las sentencias los siguientes valores: 9 Compilaciones (parse), ejecuciones, y lecturas realizadas 9 Tiempos de proceso de CPU 9 Nmero de lecturas lgicas y fsicas realizadas

P?gina de 52

9 Nmero de filas procesadas

9 Fallos producidos en la cache Esta informacin es recogida en un fichero con extension .trc. Dicho fichero se almacena en el path indicado por el parmetro USER_DUMP_DEST. El fichero generado con la traza no es editable por lo que esta utilidad debe ser combinada con TKPROF. Podemos activar la traza con SQL_TRACE para una sesin determinada de la siguiente manera: ALTER SESSION SET SQL_TRACE = TRUE; Y se desactivara: ALTER SESSION SET SQL_TRACE = FALSE; Tambin puede ser activada desde un proceso PL/SQL del siguiente modo: BEGIN DBMS_SESSION.SET_SQL_TRACE (TRUE); <plsql_procedure_call>; DBMS_SESSION.SET_SQL_TRACE(FALSE); END; En el caso de querer trazar una sesin determinada de un usuario determinado, es preciso obtener previamente el valor de los campos SID y SERIAL# de la vista del sistema V$SESSION. Se activara la traza ejecutando la sentencia: EXECUTE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(sid,serial#,TRUE); Y se desactivara: EXECUTE DBMS_SYSTEM.SET_SQL_TRACE_IN_SESSION(sid,serial#,FALSE);

7.5.2 TKPROF
El fichero con la traza obtenido con SQL_TRACE no es editable. Para poder analizar su contenido es preciso ejecutar la utilidad TKPROF. Esta utilidad se encuentra normalmente en el path $ORACLE_HOME/BIN y su nombre vara segn las versiones de Oracle (normalmente tkprof.exe). Para poder ejecutar TKPROF es requisito previo que el parmetro TIMED_STATICS tenga valor TRUE. Sintaxis TKPROF tiene como parmetros principales de ejecucin los siguientes

P?gina de 52

TKPROF <fichero_traza><fichero_salida> Donde <fichero_traza> es el fichero generado por SQL_TRACE y fichero_salida> el fichero formateado por TKPROF y a partir del cual se pueden analizar los resultados de la traza. Tkprof fichero_trc fichero_salida explain=system/password@string conexion sys=no sort=exeela Un ejemplo de la salida es el siguiente: TKPROF: Release 10.2.0.4.0 - Production on Tue Aug 30 13:11:57 2011 Copyright (c) 1982, 2007, Oracle. All rights reserved. Trace file: c:\orasac_ora_4388.trc Sort options: default ******************************************************************************** count = number of times OCI procedure was executed cpu = cpu time in seconds executing elapsed = elapsed time in seconds executing disk = number of physical reads of buffers from disk query = number of buffers gotten for consistent read current = number of buffers gotten in current mode (usually for update) rows = number of rows processed by the fetch or execute call ******************************************************************************** error connecting to database using: sys/ono123 ORA-01017: invalid username/password; logon denied EXPLAIN PLAN option disabled. ******************************************************************************** Select sourceid FROM pco_outboundqueue WHERE SERVICEID =1021 AND loadid=100 AND status IN (99, 94,98,96) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 2 0.09 3.18 503 1939 0 3645 ------- ------ -------- ---------- ---------- ---------- ---------- ---------total 4 0.09 3.19 503 1939 0 3645 Misses in library cache during parse: 1 Optimizer mode: CHOOSE Parsing user id: 67 Rows Row Source Operation ------- --------------------------------------------------3645 TABLE ACCESS BY INDEX ROWID PCO_OUTBOUNDQUEUE (cr=1939 pr=503 pw=0 time=6078386 us) 3720 INDEX RANGE SCAN PCO_OUTBOUNDQUEUECT1 (cr=18 pr=14 pw=0 time=33809 us)(object id 62699) ********************************************************************************

Select sourceid FROM pco_outboundqueue WHERE SERVICEID =1168 AND loadid=100 AND status IN (99, 94,98,96) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 1 0.01 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 4 0.18 6.39 1016 2526 0 8416 ------- ------ -------- ---------- ---------- ---------- ---------- ---------total 6 0.20 6.40 1016 2526 0 8416 Misses in library cache during parse: 1 Optimizer mode: CHOOSE Parsing user id: 67 Rows Row Source Operation ------- --------------------------------------------------8416 TABLE ACCESS BY INDEX ROWID PCO_OUTBOUNDQUEUE (cr=2526 pr=1016 pw=0 time=11156363 us) 9001 INDEX RANGE SCAN PCO_OUTBOUNDQUEUECT1 (cr=34 pr=30 pw=0 time=100193 us)(object id 62699) ******************************************************************************** Select sourceid FROM pco_outboundqueue WHERE SERVICEID =1362 AND loadid=100 AND status IN (99, 94,98,96) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 5 0.12 4.91 815 3240 0 9385 ------- ------ -------- ---------- ---------- ---------- ---------- ---------total 7 0.12 4.91 815 3240 0 9385 Misses in library cache during parse: 1 Optimizer mode: CHOOSE Parsing user id: 67 Rows Row Source Operation ------- --------------------------------------------------9385 TABLE ACCESS BY INDEX ROWID PCO_OUTBOUNDQUEUE (cr=3240 pr=815 pw=0 time=1898542 us) 9408 INDEX RANGE SCAN PCO_OUTBOUNDQUEUECT1 (cr=36 pr=31 pw=0 time=96896 us)(object id 62699) ******************************************************************************** Select sourceid FROM pco_outboundqueue WHERE SERVICEID =3012 AND loadid=100 AND status IN (99, 94,98,96) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 8 0.25 12.12 1800 4896 0 16940
P?gina de 52

------- ------ -------- ---------- ---------- ---------- ---------- ---------total 10 0.25 12.13 1800 4896 0 16940 Misses in library cache during parse: 1 Optimizer mode: CHOOSE Parsing user id: 67 Rows Row Source Operation ------- --------------------------------------------------16940 TABLE ACCESS BY INDEX ROWID PCO_OUTBOUNDQUEUE (cr=4896 pr=1800 pw=0 time=6844387 us) 17426 INDEX RANGE SCAN PCO_OUTBOUNDQUEUECT1 (cr=66 pr=58 pw=0 time=174716 us)(object id 62699) ******************************************************************************** Select sourceid FROM pco_outboundqueue WHERE SERVICEID =3050 AND loadid=100 AND status IN (99, 94,98,96) call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 1 0.00 0.00 0 0 0 0 Execute 1 0.00 0.00 0 0 0 0 Fetch 1 0.03 0.67 98 411 0 899 ------- ------ -------- ---------- ---------- ---------- ---------- ---------total 3 0.03 0.68 98 411 0 899 Misses in library cache during parse: 1 Optimizer mode: CHOOSE Parsing user id: 67 Rows Row Source Operation ------- --------------------------------------------------899 TABLE ACCESS BY INDEX ROWID PCO_OUTBOUNDQUEUE (cr=411 pr=98 pw=0 time=700632 us) 962 INDEX RANGE SCAN PCO_OUTBOUNDQUEUECT1 (cr=6 pr=3 pw=0 time=8724 us)(object id 62699)

******************************************************************************** OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 5 0.01 0.01 0 0 0 0 Execute 5 0.00 0.00 0 0 0 0 Fetch 20 0.68 27.30 4232 13012 0 39285 ------- ------ -------- ---------- ---------- ---------- ---------- ---------total 30 0.70 27.32 4232 13012 0 39285 Misses in library cache during parse: 5 OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------Parse 0 0.00 0.00 0 0 0 0 Execute 0 0.00 0.00 0 0 0 0 Fetch 0 0.00 0.00 0 0 0 0

------- ------ -------- ---------- ---------- ---------- ---------- ---------total 0 0.00 0.00 0 0 0 0 Misses in library cache during parse: 0 5 user SQL statements in session. 0 internal SQL statements in session. 5 SQL statements in session. 0 statements EXPLAINed in this session. ******************************************************************************** Trace file: c:\orasac_ora_4388.trc Trace file compatibility: 10.01.00 Sort options: default 1 session in tracefile. 5 user SQL statements in trace file. 0 internal SQL statements in trace file. 5 SQL statements in trace file. 5 unique SQL statements in trace file. 88 lines in trace file. 362 elapsed seconds in trace file. USO dbms_sqltune Para la optimizacin de sqls se puede usar el siguiente paquete de oracle: dbms_sqltune Este paquete nos permite el realizar un tuning de una determinada sentencia y nos ofrecer una serie de recomendaciones para optimizarla, para poder ejecutar este paquete el usuario ha de tener permisos sobre el rol advisor para otrogarle este rol hay que conectarse como sys y ejecutar: grant advisor to esm4; Ejemplo de uso: SQL> set serveroutput on size 999999 SQL> set long 999999 SQL> set linesize 300 SQL> col operation format a120 SQL> SQL> declare 2 3 l_task_id l_sql varchar2(20); varchar2(1000);

4 begin 5 l_sql := 'Select sourceid FROM pco_outboundqueue WHERE SERVICEID =1168 AND loadid=100 AND status IN (99,94,98,96)'; 6 7 l_task_id := dbms_sqltune.create_tuning_task ( sql_text => l_sql,

P?gina de 52

8 9 10 11 12 13

user_name => 'ESM4', scope => 'COMPREHENSIVE',

time_limit => 120, task_name => 'testing' ); dbms_sqltune.execute_tuning_task ('testing');

14 end; 15 /

PL/SQL procedure successfully completed.

SQL> select dbms_sqltune.report_tuning_task ('testing') as operation from dual;

OPERATION -----------------------------------------------------------------------------------------------------------------------GENERAL INFORMATION SECTION ------------------------------------------------------------------------------Tuning Task Name : testing Tuning Task Owner : ESM4 Scope : COMPREHENSIVE

Time Limit(seconds): 120 Completion Status : COMPLETED Started at Completed at : 09/21/2011 01:22:10 : 09/21/2011 01:23:19

-------------------------------------------------------------------------------

OPERATION -----------------------------------------------------------------------------------------------------------------------Schema Name: ESM4 SQL ID : 4qhh1vn53d2rc

SQL Text : Select sourceid FROM pco_outboundqueue WHERE SERVICEID =1168 AND loadid=100 AND status IN (99,94,98,96)

------------------------------------------------------------------------------There are no recommendations to improve the statement.

------------------------------------------------------------------------------Para el borrado de la ejecucin se debe de ejecutar: exec DBMS_SQLTUNE.DROP_TUNING_TASK('testing');

7.6

Estadsticas

Como administradores de base de datos, podemos generar estadsticas que cuantifiquen la distribucin de los datos y los modos de almacenamiento de las tablas, ndices, vistas, particiones, El optimizador basado en costes (CBOCost Based Optimizer) utiliza esta informacin para estimar cual es el plan ptimo de ejecucin de las sentencias SQL. Las estadsticas se almacenan en el diccionario de datos y pueden ser exportadas de una base de datos a otra, de manera que se pueden simular las condiciones de ejecucin de un entorno de desarrollo en uno de produccin y viceversa. Es conveniente generar estadsticas de manera peridica para un rendimiento ptimo de la base de datos. En particular deben generarse cuando: Ser necesario para optimizar tener en cuenta los siguientes puntos: 9 9 Despus de cargar gran cantidad de datos. Despus de cambiar la estructura de los objetos que componen la base de datos.

Generacin de estadsticas El optimizador basado en costes (CBO) utiliza las estadsticas para determinar los mtodos de acceso ms efectivos. Por tanto, si el tamao y la distribucin de los datos en las tablas cambia frecuentemente, el generar las estadsticas regularmente asegura que estas representen con precisin el estado de los datos. El paquete DBMS_STATS contiene los procedimientos para la generacin de estadsticas: Procedimiento Descripcin GATHER_INDEX_STATS

Estadsticas de ndices (bitmap) GATHER_TABLE_STATS Estadsticas de tablas, columnas e ndices estticos GATHER_SCHEMA_STATS objetos del esquema GATHER_DATABASE_STATS objetos de la BD GATHER_SYSTEM_STATS Estadsticas para todos los Estadsticas para todos los

Estadsticas del sistema (CPU, I/O)


P?gina de 52