You are on page 1of 41

Proyecto: COM Estndar de Codificacin Oracle

Resumen
Manual de Uso de SQL.

Registro de modificaciones
Versin 1.0 1.1 1.2 Descripcin [o descripcin de cambios] Versin Inicial Revisin versin inicial: se incluyen premisas para el desarrollo batch Actulizaciones 10G y manejo de tablas Autor everis everis D. Arias Fecha creacin 12/06/2006 29/08/2006 29/08/2011 Aprobado por Fecha aprobacin 12/06/2006 29/08/2006 29/08/2011

Contenido
1. Convenciones de Nomenclatura. ........................................................................................... 4 1.1 Nomenclatura ...................................................................................................................... 4 1.2 Indentacin .......................................................................................................................... 4 1.3 Programacin ...................................................................................................................... 4 2. ndices ....................................................................................................................................... 5 2.1 ndices compuestos ............................................................................................................. 5 2.2 ndices bitmap...................................................................................................................... 5 2.3 Forzar la no utilizacin de un ndice. ................................................................................... 6 2.4 Recomendaciones al momento de utilizar ndices. ............................................................. 6 2.5 Reducir el trfico en la base de datos ................................................................................. 7 2.6 Hints ..................................................................................................................................... 7 2.6.1 Hints para escoger el tipo de optimizacin ................................................................ 8 2.6.2 Hints para mtodo de acceso .................................................................................... 9 2.6.3 Hints para ordenacin de joins ................................................................................10 2.6.4 Hints para operaciones de joins ..............................................................................11 3. Recomendaciones prcticas ................................................................................................12 3.1 Sentencias con valores nulos ............................................................................................12 3.2 Sentencias con la clusula DECODE .............................................................................13 3.3 Sentencias con la clusula WHERE. Uso de los ndices ...............................................14 3.4 Contar filas de tablas .........................................................................................................15 3.5 Usar clusula WHERE en lugar de la clusula HAVING .............................................15 3.6 Minimizar el nmero de tablas en subconsultas ...............................................................16 3.7 No abusar de las JOIN de tablas.......................................................................................16 3.8 Usar JOINS de tablas en lugar de la clusula EXISTS ................................................16 3.9 Usar la clusula EXISTS en lugar de JOINS de tablas ................................................17 3.10 Usar la clusula EXISTS en lugar de DISTINCT ................................................17 3.11 Usar la clusula NOT EXISTS en lugar de la clusula NOT IN .........................18 3.12 Usar la clusula UNION ALL en lugar de la clusula UNION ............................18 3.13 Usar la clusula IN O UNION en lugar de la clusula OR ...............................19 3.14 Usar EXISTS en lugar de COUNT(*) .......................................................................19 3.15 Lgica condicional ...................................................................................................20 3.15.1 Usar ELSIF con clusulas mutuamente exclusivas ...................................20 3.15.2 Usar IFELSIF para evaluar condiciones simples ....................................20

2005 - everis

Page 1 of 41

3.15.3 Reemplazar sentencias IF con expresiones booleanas .............................21 3.15.4 Optimizacin de sentencias condicionales .................................................21 3.16 Control de flujo .........................................................................................................22 3.16.1 No usar sentencias GOTO .........................................................................22 3.17 No usar sentencias EXECUTE ................................................................................22 3.17.1 Uso de bloques annimos ..........................................................................22 3.18 Bucles ......................................................................................................................22 3.18.1 Uso de EXIT y RETURN en bucles WHILE y FOR ....................................22 3.18.2 Uso de EXIT en bucles LOOP ....................................................................22 3.18.3 Usar bucles LOOP para evitar el cdigo redundante requerido por los bucles WHILE ..............................................................................................23 3.18.4 No declarar el ndice para el bucle FOR ....................................................23 3.18.5 Recorrer colecciones usando FIRST, LAST y NEXT en bucles .................24 3.18.6 Mover expresiones estticas fuera de los bucles y sentencias SQL 24 3.19 Uso de datos ............................................................................................................25 3.19.1 Uso de %TYPE y %ROWTIPE para la definicin de variables ..................25 3.19.2 Evitar columnas LONG o LONG RAW .......................................................25 3.19.3 Uso de constantes y parmetros ................................................................25 3.20 Acceso a la Base de Datos ......................................................................................26 3.20.1 Construccin de consultas..........................................................................26 3.20.2 Construccin de cursores ...........................................................................27 3.21 Tamao de los Objetos PL-SQL ..............................................................................28 3.21.1 Objetos sin referenciar ................................................................................28 3.22 Procesos batch ........................................................................................................29 3.22.1 INSERT-SELECT .......................................................................................29 3.22.2 Eliminacin de ndices y recreacin de ndices ..........................................29 3.23 Otros ........................................................................................................................29 3.23.1 Usar bloques annimos dentro de sentencias IF para conservar recursos ..................................................................................................29 3.23.2 Excepciones ...............................................................................................30 3.24 Otras reglas a tener en cuenta ................................................................................30 3.25 Buenas Prcticas para versiones 10G. ...................................................................31 3.25.1 Optimizador basado en costo (CBO) ..........................................................31 3.25.2 Tablas. ........................................................................................................32 3.25.3 Tablespace (espacio de tablas) .................................................................33 3.25.4 Concepto de Datafile (fichero de datos) .....................................................35 3.25.5 Concepto de Segment (segmento, trozo, seccin) ....................................36 3.25.6 Concepto de Extent (extensin) .................................................................37 3.25.7 Concepto de Data block (bloque de datos) ................................................39 4. Referencias bibliogrficas ....................................................................................................41

2005 - everis

Page 2 of 41

COM

Estndar de Codificacin Oracle

Objetivo
El presente documento tiene como objeto el establecer una serie de guas o normas estndar de referencia que sirvan para unificar los criterios en el desarrollo de nuevos programas escritos en lenguaje SQL, permitiendo realizar un diseo ptimo de nuestros procesos en cuanto al acceso a la base de datos se refiere, mejorando de este modo el rendimiento de las aplicaciones. Adems se abordarn conceptos tales como: Descripcin de los pasos involucrados en el proceso de una sentencia SQL. Necesidad de construccin de ndices. Obtencin del mximo rendimiento de las sentencia.(Estndares de programacin, sintaxis alternativas, uso de hint,..)

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 3 de 41

COM

Estndar de Codificacin Oracle

1. Convenciones de Nomenclatura.
1.1 Nomenclatura
Prefijos de ficheros: pls (mdulo), trg (trigger), ddl (DDLs), sp (Stored Proc), Prefijos de mbito: g (global), v (local) Prefijos de variables: k (constante), c (cursor), r (record), Sufijos de variables: (input), o (output), io (input / output)

1.2 Indentacin
Tabulador para cdigo Espacios en blanco para sentencias SQL

1.3 Programacin
Una sentencia por lnea. No utilizar parntesis redundantes No reutilices variables Utiliza %type siempre que sea posible

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 4 de 41

COM

Estndar de Codificacin Oracle

2. ndices
Los ndices pueden mejorar el rendimiento de las consultas o modificaciones que seleccionan un pequeo porcentaje de las filas de una tabla. En general, se deben crear ndices para las tablas sobre las cuales los accesos (consultas o modificaciones) son ms frecuentes, retornando un nmero de filas inferior al 25% del total. En estos casos, la utilizacin de un ndice puede ser efectiva. Para seleccionar las columnas a indexar seguir las siguientes pautas: Columnas que son frecuentemente utilizadas en clusulas WHERE. Columnas que son frecuentemente utilizadas en joins de tablas en sentencias SQL. nicamente indexar columnas con buena selectividad. La selectividad de un ndice es el porcentaje de filas de una tabla que tienen el mismo valor para la columna indexada. La selectividad de un ndice es buena si pocas filas tienen el mismo valor. Tener presente que Oracle implcitamente crea ndices sobre las columnas de todas las claves primarias y nicas que se hayan definido con reglas de integridad. Estos ndices son los ms selectivos y los ms eficientes. No indexar las columnas con pocos valores diferentes. Estas columnas normalmente tienen una selectividad baja y no se optimiza su rendimiento, menos en el caso que se seleccionen frecuentemente las filas con valores menos frecuentes que otros valores de la columna. En estos casos se recomienda crear ndices bitmap, al menos que sea una aplicacin OLTP con mucha concurrencia. No indexar columnas que frecuentemente son modificadas. Las sentencias UPDATE que modifican columnas indexadas y sentencias INSERT y DELETE que modifican las tablas indexadas tardan ms en ejecutarse que si no estuvieran indexadas. Cada sentencia SQL debe de modificar los datos en los ndices igual que los datos en las tablas. No indexar columnas que slo aparezcan en las clusulas WHERE con operadores o funciones. Una clusula WHERE que utiliza una funcin (como MIN o MAX) o un operador sobre una columna indexada no tiene disponible el acceso por ndice. En estos casos, existe la posibilidad de crear ndices basados en funciones. Indexar claves forneas de integridad referencial cuando un nmero elevado de sentencias concurrentes INSERT, UPDATE y DELETE acceden a tablas padre e hijo. As, un ndice permite a Oracle modificar un dato en el hijo sin bloquear la tabla padre.

2.1 ndices compuestos


Muchas veces es mejor definir ndices compuestos que simples (de una columna). Un ndice compuesto es un ndice que esta compuesto de ms de una columna. Para definir ndices compuestos seguir las siguientes guas: Indexar columnas que frecuentemente se utilizan juntas en clusulas WHERE con condiciones combinadas con el operador AND, especialmente si su combinacin tiene mejor selectividad que la que tienen individualmente. Si varias consultas seleccionan el mismo conjunto de columnas que adems aparecen una o ms de ellas en la clusula WHERE, considerar crear un ndice compuesto que contenga todas estas columnas. Asegurarse de crear el ndice de forma que las columnas sobre las cuales se basa la columna (columnas que aparecen en la clusula WHERE) estn al principio y consecutivamente. Por ejemplo, si tenemos las consultas:

2.2 ndices bitmap


El propsito de un ndice es proveer punteros a las filas de una tabla que contienen el valor de una clave dada. En un ndice normal, se almacena una lista de rowids para cada clave que corresponde a las filas que contienen ese valor. En un ndice bitmap, se utiliza un mapa de bits para cada valor de la clave en vez de una lista de rowids.
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 5 de 41

COM

Estndar de Codificacin Oracle

Los ndices bitmap pueden mejorar el rendimiento de las consultas que tienen las siguientes caractersticas: La clusula WHERE contiene mltiple predicados con baja o media cardinalidad en sus columnas. Estos predicados individualmente seleccionan un gran nmero de filas. Los ndices bitmap han sido creados en todas o algunas columnas de baja/media cardinalidad. Las tablas consultadas contienen muchas filas. Se pueden utilizar ndices bitmap para evaluar las condiciones de una sola tabla. Adems, son favorables para consultas complejas ad-hoc que contienen largas clusulas WHERE. Los ndices bitmap no son adecuados para aplicaciones OLTP con gran nmero de transacciones concurrentes que modifican datos. Estos ndices principalmente se utilizan en aplicaciones de datawarehouse donde los usuarios normalmente realizan consultas en vez de modificar datos.

2.3 Forzar la no utilizacin de un ndice.


En algunos casos, se puede querer evitar utilizar un ndice existente para el acceso a una sentencia SQL. Por ejemplo, si sabemos que el ndice no es selectivo y que el acceso secuencial de toda la tabla (full table scan) es ms eficiente. Para forzar al optimizador para que no utilice un ndice, existen los siguientes mtodos: Utilizar el hint NO_INDEX. Utilizar un hint FULL para forzar al optimizador a escoger el full table scan en vez de un ndice (index scan). Utilizar el hint INDEX, INDEX_COMBINE o AND_EQUAL para forzar al optimizador a utilizar un ndice o ndices determinados. Modificar la sentencia haciendo que el acceso por el ndice no est disponible. Este mtodo nicamente es vlido si se est trabajando con el optimizador basado en reglas.

2.4 Recomendaciones al momento de utilizar ndices.


Indexar todas las primary key y foreign key. Para ndices concatenados tenemos dos opciones para elegir la primera columna: Poner la columna usada ms frecuentemente en la clusula WHERE. Poner la ms selectiva. (esta opcin es importante con CBO). Asegurarse que las columnas que se estn indexando no aparecen dentro de expresiones o conversiones. Bsqueda por NDICE versus recorrido completo de TABLA Con RBO, el optimizador siempre escoge el acceso va ndice. Con CBO el optimizador compara el coste acceso va ndice con el recorrido completo de la tabla. El coste de un recorrido completo depende del nmero de bloques que Oracle puede leer simultneamente y del nmero de bloques que ocupa la tabla. El coste va ndice se basa en el porcentaje de filas seleccionadas de la tabla. Es ms eficaz cuando se recupera un pequeo porcentaje de filas de la tabla (no ms de 25%). Eficiencia de un Acceso va NDICE Cuando una consulta devuelve una sola fila, el optimizador normalmente elige el acceso va ndice. Cuando una consulta devuelve ms de una fila, el optimizador divide el nmero de valores diferentes en la columna por el nmero de filas en la tabla.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 6 de 41

COM

Estndar de Codificacin Oracle

Cuando en una consulta se especifica un rango no limitado el optimizador utiliza el valor mayor y el menor de la columna y estima el nmero de filas que devuelve la consulta. Cuando la consulta especifica un rango limitado de valores el optimizador asume que la consulta devuelve el 25% de las filas. Cuando hay dos variables de recuperacin en una condicin de rango limitado, el optimizador asume que la consulta devuelve el 50% de las filas.

2.5 Reducir el trfico en la base de datos


En entornos cliente/servidor, el trfico de datos del cliente a la base de datos hace que ralentice el sistema. Si en un acceso necesitamos recuperar un campo y posteriormente se necesita recuperar otro campo diferente, podemos realizar una seleccin de los dos campos y recuperamos de un acceso los dos campos que necesitamos. Para reducir este trfico de datos, estar prohibido recuperar todos los campos de una tabla determinada mediante la instruccin: SELECT * FROM tabla y la sustituiremos por: SELECT <lista de campos> FROM tabla

2.6 Hints
El diseador de una aplicacin tiene informacin sobre los datos que el optimizador Oracle desconoce. Por ejemplo, el diseador sabe que un cierto ndice es muy selectivo para ciertas consultas. Puede utilizar hints para forzar al optimizador a utilizar este ndice. Los hints slo son aplicables en el caso que se haya activado el optimizador basado en costes. Los hints son indicadores que se dan al optimizador. Permiten anteponer las decisiones del diseador a las del optimizador. Se pueden utilizar hints para especificar: El tipo de optimizacin a utilizar para una sentencia. El mtodo de acceso a una tabla accedida por la sentencia. El orden de join para una sentencia con join. Operacin de join en una sentencia con join. Los hints se aplican nicamente para la optimizacin del bloque de la sentencia donde aparece. Un bloque de una sentencia es una de las siguientes sentencias o partes de sentencias: Una simple sentencia SELECT, UPDATE o DELETE. Una sentencia padre o subquery de una sentencia compleja. Una parte de una consulta compuesta. Sintaxis Un bloque de una sentencia slo puede tener un comentario que contiene hints. El comentario slo se puede poner detrs de las palabras SELECT, UPDATE y DELETE: SELECT UPDATE DELETE Donde /*+ hint */

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 7 de 41

COM DELETE, SELECT, UPDATE sentencia

Estndar de Codificacin Oracle palabras donde comienza el bloque de la

Hint

signo + que indica a Oracle que interprete el comentario como una lista de hints. Los signos + y /* se tienen que escribir juntos (sin ningn espacio en blanco). hint. Si hay ms de un hint, se deben de separar con un blanco.

2.6.1 Hints para escoger el tipo de optimizacin


Permiten escoger entre optimizador basado en costes y basado en reglas, y dentro del basado en costes, entre el de mejor throughput (procesamiento) y el de mejor tiempo de respuesta. ALL_ROWS Indica que se debe escoger un acceso basado en costes para optimizar un bloque de una sentencia con el mejor throughput (mnimo tiempo necesario para procesar todas las filas accedidas por la sentencia). FIRST_ROWS Indica que se debe escoger un acceso basada en costes para optimizar un bloque de una sentencia con el mejor tiempo de respuesta (mnimo tiempo necesario para procesar la primera fila accedida por la sentencia). CHOOSE Este hint especifica que el optimizador escoja entre acceso basado en reglas y basado en costes. El optimizador basa su seleccin en la existencia de estadsticas de las tablas accedidas en la sentencia. Si el diccionario de datos tiene estadsticas al menos de una de estas tablas, entonces el optimizador escoge el acceso basado en costes con el mejor throughput. Si no hay estadsticas, usa el basado en reglas.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 8 de 41

COM RULE

Estndar de Codificacin Oracle

Indica explcitamente que se debe escoger el optimizador basado en reglas para ese bloque de la sentencia. Este hint hace que el optimizador siempre ignore otros hints especificados en el mismo bloque de la sentencia.

2.6.2 Hints para mtodo de acceso


Cada hint indica un mtodo de acceso a la tabla. Especificando uno de estos hints, el optimizador escoge el acceso indicado slo si est disponible, basndose en la existencia de un ndice o cluster y en la construccin sintctica de la sentencia SQL. Si no est disponible, lo ignora. Se tiene que especificar la tabla a acceder exactamente como se indica en la sentencia. Si en la sentencia se utiliza un alias de la tabla, tambin se debe utilizar en el hint. FULL Indica que se debe escoger un full scan de la tabla especificada: FULL(tabla). ROWID Indica al optimizador que escoja el acceso a la tabla especificada va ROWID: ROWID(tabla). CLUSTER Indica al optimizador que escoja el acceso a la tabla especificada va cluster: CLUSTER(tabla). HASH Indica al optimizador que escoja el acceso a la tabla especificada va hash: HASH(tabla). NDICE Indica explcitamente que se debe escoger un acceso por ndice para la tabla especificada:
INDEX( tabla ndice )

INDEX_ASC Indica explcitamente que se debe escoger un acceso por ndice para la tabla especificada. Oracle accede a los valores del ndice en orden ascendente.
INDEX_ASC (tabla ndice )

INDEX_COMBINE Explcitamente escoge un acceso va bitmap para una tabla. Si no se especifica ningn ndice, el optimizador escoge cualquier combinacin booleana de ndices bitmap que tenga el mejor coste estimado para la tabla. Si se especifican varios ndices, el optimizador escoge utilizar alguna combinacin booleana de estos ndices bitmap.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 9 de 41

COM

Estndar de Codificacin Oracle

INDEX_JOIN Indica al optimizador que utilice un ndice join como va de acceso. Para que tenga efecto este hint, debe existir un nmero pequeo de ndices que contengan todas las columnas requeridas para resolver la seleccin. INDEX_DESC Indica explcitamente que se debe escoger un acceso por ndice para la tabla especificada. Oracle accede a los valores del ndice en orden descendente. Este hint no tiene efecto cuando en la sentencia hay ms de una tabla. En este caso siempre accede de forma ascendente. INDEX_FFS Este hint causa un fast full index scan en vez de un full table scan. NO_INDEX Explcitamente se rechaza un conjunto de ndices para la tabla especificada. Si el hint especifica un ndice disponible, el optimizador no lo considera. Otros ndices no especificados son considerados. Si el hint no especifica ningn ndice, el optimizador no considera un scan sobre cualquier ndice de la tabla. Este escenario es equivalente al hint NO_INDEX con la especificacin de todos los ndices de la tabla. Si un hint NO_INDEX y un hint de ndice (INDEX, INDEX_ASC, INDEX_DESC, INDEX_COMBINE, o INDEX_FFS) especifican los mismos ndices, entonces son ignorados y el optimizador considera los ndices especficos.

AND_EQUAL Indica que se debe escoger un plan de ejecucin que combine accesos sobre varios ndices de una sola columna (cada uno). USE_CONCAT Este hint fuerza a combinar condiciones OR en la clusula WHERE de una consulta para ser transformada en una consulta compuesta usando el operador UNION ALL. Normalmente, esta transformacin ocurre slo si el coste de la consulta, utilizando las concatenaciones, es ms barato que sin ellas. NO_EXPAND Evita que el optimizador basado en costes considere una OR-expansin para consultas que tienen condiciones de OR o listas IN en la clusula WHERE. Normalmente, el optimizador considera utilizar OR-expansin si el coste es menor que no utilizndola.

2.6.3 Hints para ordenacin de joins


ORDERED Este hint provoca que Oracle haga join de las tablas en el orden que aparecen en la clusula FROM. Por ejemplo, esta sentencia hace join de la tabla t1 con la t2 y despus el resultado de este join con la tabla t3: SELECT /*+ ORDERED */ t1.col1, t2.col2, t3.col3 FROM t1,t2,t3 WHERE t1.col1 = t2.col1 AND t2.col1 = t3.col1 Si se omite el hint, el optimizador escoge el orden en el cual se realiza la join de las tablas. STAR
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 10 de 41

COM

Estndar de Codificacin Oracle Este hint fuerza el uso de un plan estrella. Un plan estrella tiene la tabla ms grande en la ltima consulta del join order y realiza el join con un nested loops join sobre un ndice concatenado. Este hint se aplica cuando hay al menos 3 tablas, el ndice concatenado de la tabla ms grande tiene al menos tres columnas, y no hay conflictos de acceso o hints de mtodos de join. El optimizador tambin considera diferentes permutaciones de las tablas pequeas. Usualmente, si se analizan las tablas, el optimizador selecciona un eficiente plan estrella.

2.6.4 Hints para operaciones de joins


USE_NL Este hint hace que Oracle realice una join de cada tabla especificada con otras filas mediante nested loops siendo la tabla especificada la interior del loop. Muchas veces, un nested loops join retorna la primera fila antes que un sort-merge join. Un nested loops join puede retornar la fila despus de leer la fila seleccionada de una tabla y el primer emparejamiento (matching) de otra y combinarlas, mientras un sort-merge join no puede retornar la primera fila hasta leer y ordenar todas las filas seleccionadas de las dos tablas y combinar las primeras filas de cada ordenacin. USE_MERGE Este hint hace que Oracle realice una join de cada tabla especificada con otras filas mediante un sort-merge (ordenacin-agrupacin). USE_HASH Este hint causa que Oracle realice una join de cada tabla especificada con las filas resultantes de las operaciones anteriores con un hash join. DRIVING_SITE Fuerza que la ejecucin de la consulta se realice en un lugar diferente al seleccionado por Oracle. Este hint puede ser utilizado tanto con el optimizador basado en reglas como con el basado en costes. LEADING Este hint causa que Oracle utilice la tabla especificada como la primera tabla en el orden del join. Si se especifican dos o ms hints LEADING sobre diferentes tablas, se ignoran todos ellos. Si se especifica el hint ORDERED, quedan sin efecto todos los hints LEADING.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 11 de 41

COM

Estndar de Codificacin Oracle

3. Recomendaciones prcticas
En este apartado se realiza unas recomendaciones sobre la creacin de sentencias SQL y su rendimiento en el gestor de base de datos. A continuacin, se van a realizar unas recomendaciones para obtener el mximo rendimiento a la consulta creada y al sistema gestor de la base de datos. Como norma principal, cualquier acceso a la base de datos tiene que estar realizado de forma ptima.

3.1 Sentencias con valores nulos


Es importante conocer el uso que se puede dar al valor nulo, dado que usualmente es utilizado: Un valor nulo nunca es igual a (=) nada (incluyendo cero, espacio). Un valor nulo nunca no es igual a (!= o <>) nada. Un valor nulo nunca es menos que (<) o menos o igual que (<=) nada. Un valor nulo nunca es mayor que (>) o mayor o igual que (>=) nada. Si se ejecuta una comparacin con un valor NULL, el registro ser rechazado. Ninguna de las siguientes sentencias retornarn filas: SELECT X FROM DUAL WHERE X = NULL; SELECT X FROM DUAL WHERE NULL IN (A, B, NULL); En cambio, las siguientes sentencias si que retornarn filas: SELECT X FROM DUAL WHERE X = NVL (NULL, X); SELECT X FROM DUAL WHERE NULL IS NULL; Como las buenas reglas, existen algunas excepciones. Un valor NULL es igual a un valor nulo en las siguientes situaciones limitadas: En parmetros DECODE (donde NULL es un valor dentro de la lista de comparacin). SELECT DECODE (ciudad, M, Madrid, G, Guadalajara, NULL, Desc.) ciudad FROM ciudades WHERE nombre = Pepe; En parmetros GROUP BY (donde varias filas tienen una columna con un valor NULL): SELECT ciudad, count(*) FROM ciudades GROUP BY ciudad;
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 12 de 41

COM

Estndar de Codificacin Oracle

En parmetros DISTINCT (donde haya un nmero de filas que tengan una columna con un valor NULL): SELECT count (DISTINCT ciudad) FROM ciudades; En funciones UNION/MINUS/INTERSECT (donde haya un nmero de filas que tengan una columna con un valor NULL): SELECT nombre, ciudad FROM ciudades UNION SELECT nombre, null FROM localidad

3.2 Sentencias con la clusula DECODE


Algunas veces, se necesita una forma de contar y/o sumar condiciones a variables para un grupo de filas. La sentencia DECODE provee un mecanismo muy eficiente para hacer esto. Con esta sentencia podemos: Reducir sentencias de procesamiento. Podemos buscar en una tabla registros con diferentes filtros. Ejemplo: Queremos buscar el nmero de empleados y la suma de sus salarios de todos los empleados del departamento 0020 y que su nombre empiece por SMITH. Lo mismo con el departamento 0030. Se poda hacer as: SELECT count(*), SUM (salario) FROM empleados WHERE n_dpto = 0020 AND nombre LIKE SMITH%;

SELECT count(*), SUM (salario) FROM empleados WHERE n_dpto = 0030 AND nombre LIKE SMITH%; Esto, podemos hacerlo ms eficiente con la instruccin DECODE. SELECT COUNT (DECODE(n_dpto, 0020, X, NULL)) count20, COUNT (DECODE(n_dpto, 0030, X, NULL)) count30, SUM (DECODE(n_dpto, 0020, salario, NULL)) sal20, SUM (DECODE(n_dpto, 0030, salario, NULL)) sal30 FROM empleados WHERE nombre LIKE SMITH%; Usar DECODE en sentencias ORDER BY y GROUP BY. Se puede necesitar especificar muchas filtros en sentencias ORDER BY para recuperar filas. Como la consulta es idntica y lo nico que cambia es el ORDER BY, se puede realizar con la instruccin DECODE.
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 13 de 41

COM SELECT FROM empleados WHERE nombre LIKE SMITH%

Estndar de Codificacin Oracle

ORDER BY DECODE (:BLK.SEQN_FLD, E, n_emp, D, n_dept); Lo mismo se puede hacer con la instruccin GROUP BY. SELECT FROM empleados WHERE nombre LIKE SMITH% GROUP BY DECODE (:INPUT, E, n_emp, D, n_dept); Debemos tener en cuenta algunas desventajas. Si se usa DECODE dentro de instrucciones ORDER BY y GROUP BY no se pueden utilizar ndices. Por ello, el procesamiento de filas puede ser lento. Por eso es recomendado solo cuando el nmero de filas retornado sea pequeo.

3.3 Sentencias con la clusula WHERE. Uso de los ndices


Es casi imprescindible que la clusula WHERE utilice ndices para elevar el rendimiento de la consulta. Muchas veces se crean sentencias sin usar ndices, que se pueden reescribir para que s los utilicen. En los siguientes ejemplos, veremos clusulas que no usan ndices, y cmo podemos reescribirlos para que los utilicen. . EJEMPLOS La funcin SUBSTR deshabilita el ndice cuando se usa con una columna indexada El operador != (no igual) no puede utilizar ndices MENOS EFICIENTE
SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE SUBSTR(cuenta, 1, 7) = CAPITAL;

MAS EFICIENTE
SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cuenta LIKE CAPITAL%;

SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cantidad != 0;

SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cantidad > 0; SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE fecha_trans BETWEEN TRUNC (SYSDATE) AND TRUNC(SYSDATE) + .99999; SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cuenta = AMEX AND tipo_cuenta = A; SELECT cuenta, fecha_trans, cantidad

La funcin TRUNC deshabilita los ndices

SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE TRUNC(fecha_trans) = TRUNC (SYSDATE);

El operador || deshabilita los ndices

SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cuenta || tipo_cuenta = AMEXA;

Los operadores aritmticos (+, -, * y /) deshabilitan los ndices


Archivo: 178900375.doc.ms_office 2005 - everis

SELECT cuenta, fecha_trans, cantidad

Pgina 14 de 41

COM

Estndar de Codificacin Oracle

(clculos)

FROM transaccion WHERE cantidad + 3000 < 5000;

FROM transaccion WHERE cantidad < 2000; SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cuenta LIKE NVL (:nombre_cuenta, %); SELECT nombre FROM pruebas.empleados WHERE salario=to_number(1000); select nombre from empleados where nif like 123%;

Los ndices no son usados tampoco cuando una columna o varias aparecen en ambos lados del operador

SELECT cuenta, fecha_trans, cantidad FROM transaccion WHERE cuenta = NVL (:nombre_cuenta, cuenta); SELECT nombre FROM pruebas.empleados WHERE to_char(salario)=1000;

Conversin de la columna indexada

El comando like sobre un campo con un ndice. Si se utilizan operadores %, a mayor tamao de la parte no variable inicial mejor rendimiento Uso del comando like con fechas y nmeros

select nombre from empleados where nif like 1%;

select salario from empleados where contratado like '23/12/02'; select nombre from empleados where salario like 100

select salario from empleados where contratado='23/12/02'; select nombre from empleados where salario=100;

3.4 Contar filas de tablas


Aunque en general se piense lo contrario, la instruccin COUNT(*) es ms rpida que COUNT(1), y si la columna tiene un ndice COUNT(campo_con_indice) entonces es ms rpida que COUNT(*). En general, COUNT (INDEX_COLUMN) es un 5% ms rpido que COUNT(*) y esta ltima instruccin es entre un 15% y un 20% ms rpida que COUNT(1). Adicionalmente es preferible usar EXISTS en lugar de count(*):

3.5 Usar clusula WHERE en lugar de la clusula HAVING


La clusula HAVING filtra las filas seleccionadas solo despus de ir a la tabla a por todas las filas. Esto incluye el ordenarlas y compararlas. Ejemplo: MENOS EFICIENTE SELECT ciudad, AVG (poblacion) FROM localizacion
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 15 de 41

COM GROUP BY ciudad

Estndar de Codificacin Oracle

HAVING ciudad != MADRID AND ciudad != GUADALAJARA; MS EFICIENTE SELECT ciudad, AVG (poblacion) FROM localizacion WHERE ciudad != MADRID AND ciudad != GUADALAJARA GROUP BY ciudad;

3.6 Minimizar el nmero de tablas en subconsultas


En sentencias como SELECT y UPDATE que tengan subconsultas, se intentar reducir el nmero de tablas accedidas desde ellas. Ejemplo: MENOS EFICIENTE SELECT nombre_empleado FROM empresa WHERE categoria = (SELECT MAX(categoria) FROM categ_emp) AND salario = (SELECT MAX(salario) FROM categ_emp) AND deptno = 0020; MS EFICIENTE SELECT nombre_empleado FROM empresa WHERE (categoria, salario) = (SELECT MAX(categoria), MAX(salario) FROM categ_emp) AND deptno = 0020;

3.7 No abusar de las JOIN de tablas


No deben realizarse JOINS de ms de cinco tablas dentro de una misma sentencia SELECT. El optimizador de ORACLE no est diseado para trabajar con JOINS de ms de cinco tablas, por lo que no se garantiza su correcto funcionamiento.

3.8 Usar JOINS de tablas en lugar de la clusula EXISTS


En general, se ha de considerar la unin de tablas mejor que especificar subconsultas cuando el porcentaje de filas recuperadas con xito de la tabla principal sea alto. Ejemplo: MENOS EFICIENTE SELECT nombre_empleado FROM empresa E WHERE EXISTS (SELECT X FROM dept WHERE dept_no = E.dept_no AND dept_cat = A); MS EFICIENTE
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 16 de 41

COM SELECT nombre_empleado FROM depto D, empresa E WHERE E.dept_no = D.dept_no AND D.dept_cat = A;

Estndar de Codificacin Oracle

3.9 Usar la clusula EXISTS en lugar de JOINS de tablas


Hay que considerar separar algunas uniones de tablas y separarlas en subconsultas cuando el porcentaje de filas recuperadas con xito de la tabla principal sea pequeo. Si el porcentaje de filas es alto pueden ser filtradas de la tabla principal antes de ejecutar las validaciones contra la segunda tabla, y entonces el nmero de lecturas fsicas ser drsticamente reducido. Ejemplo: MENOS EFICIENTE SELECT nombre_empleado FROM dept D, empresa E WHERE E.dept_no = D.dept_no AND E.tipo_emp = MANAGER AND D.dept_cat = A; MS EFICIENTE SELECT nombre_empleado FROM empresa E WHERE EXISTS ( SELECT X FROM dept WHERE dept_no = E.dept_no AND D.dept_cat = A) AND tipo_emp = MANAGER; En una sentencia WHERE, la clusula EXISTS debe ser colocada al principio si se usa un operador AND y al final si se utiliza un operador OR.

3.10 Usar la clusula EXISTS en lugar de DISTINCT


Hay que evitar el uso de JOINS que requieren el calificador DISTINCT en la lista del SELECT cuando haya subconsultas que son usadas para determinar informacin del maestro en una relacin uno a muchos (por ejemplo, departamentos que tienen empleados). La alternativa ms rpida es con la clusula EXISTS. Ejemplo: MENOS EFICIENTE SELECT DISTINCT dept_no, nombre_dept FROM dept D, emp E WHERE D.dept_no = E.dept_no; MS EFICIENTE SELECT dept_no, nombre_dept FROM dept D, WHERE EXISTS (SELECT X FROM emp E WHERE E.dept_no = D.dept_no));
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 17 de 41

COM

Estndar de Codificacin Oracle

3.11 Usar la clusula NOT EXISTS en lugar de la clusula NOT IN


En subconsultas, la clusula NOT IN realiza una ordenacin interna. En estos casos, es recomendable reemplazar NOT IN por una columna indexada con la clusula NOT EXISTS. (y EXISTS en lugar de IN) Ejemplo: MENOS EFICIENTE SELECT FROM emp WHERE dept_no NOT IN (SELECT dept_no FROM dept WHERE dept_cat = A); MS EFICIENTE SELECT FROM emp E WHERE NOT EXISTS (SELECT dept_no FROM dept WHERE dept_no = E.deptno AND dept_cat = A); El siguiente ejemplo es equivalente al anterior y tambin es ms eficiente que la clusula NOT IN SELECT FROM emp E, dept D WHERE E.deptno=D.dept_no(+) AND D.dept_no IS NULL;

3.12 Usar la clusula UNION ALL en lugar de la clusula UNION


Cuando se incluye en una consulta la sentencia UNION, se debera siempre preguntar si con la clusula UNION ALL es suficiente. La clusula UNION fuerza que todas las filas retornadas por cada subconsulta de la UNION estn ordenadas y luego sean unidas entre s para retornar el resultado final de la UNION. Una UNION ALL simplemente retorna todas las filas incluyendo duplicados y no ejecuta ninguna ordenacin, combinacin o filtro. La mayora de las consultas que incluyen la sentencia UNION pueden ser remplazadas con UNION ALL. Ejemplo: MENOS EFICIENTE SELECT num, balance FROM debito_transaccion WHERE fecha = 31-DEC-95 UNION
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 18 de 41

COM SELECT num, balance FROM credito_transaccion WHERE fecha = 31-DEC95; MS EFICIENTE SELECT num, balance FROM debito_transaccion WHERE fecha = 31-DEC-95 UNION ALL SELECT num, balance FROM credito_transaccion WHERE fecha = 31-DEC95;

Estndar de Codificacin Oracle

3.13 Usar la clusula IN O UNION en lugar de la clusula OR


En general, es mejor utilizar clusulas IN y/o UNION en vez de la clusula OR en una sentencia WHERE. Esto ser efectivo si la columna est indexada. Si se usa la clusula OR, se pondrn primero las columnas que estn indexadas, y luego las que no lo estn. Ejemplo: MENOS EFICIENTE SELECT FROM localidad WHERE loc_id = 10 OR loc_id = 20 OR loc_id = 30; MS EFICIENTE SELECT FROM localidad WHERE loc_in IN (10,20,30);

3.14 Usar EXISTS en lugar de COUNT(*)


Hay ocasiones en que nos interesa saber si hay alguna fila con una caracterstica, no el nmero de registros de una tabla. Ejemplo: SELECT count(*) FROM empleados WHERE salario=1000 <= COLUMNA SIN INDICE

En este caso estaremos haciendo un FULL SCAN de la tabla empleados. Puede ser ms interesante ejecutar lo siguiente: SELECT 1 FROM dual WHERE Exists (SELECT 1
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 19 de 41

COM FROM empleados WHERE salario=1000);

Estndar de Codificacin Oracle

El FULL SCAN sobre empleados se detendr en cuanto encuentre la primera fila. (evitar FULL SCANS).

3.15 Lgica condicional


3.15.1 Usar ELSIF con clusulas mutuamente exclusivas
Cuando necesitamos escribir lgica condicional con mltiples clusulas que son exclusivas entre s debemos usar ELSIF (las condiciones a evaluar tienen que ir de la ms restrictiva a la menos restrictiva) IF cond1 THEN .. ELSIF cond2 THEN ELSIF cond3 THEN . ELSE . ENDIF; Si, por el contrario, usamos mltiples IFs cada clusula ser evaluada con el consiguiente tiempo de procesado perdido en evaluar condiciones que sern siempre falsas. IF cond1 THEN .. ENDIF; IF cond2 THEN ENDIF; IF cond3 THEN . ELSE . ENDIF;

3.15.2 Usar IFELSIF para evaluar condiciones simples


Cuando escribimos clusulas condicionales con IF debemos hacerlo de forma que el cdigo permanezca lo ms legible y entendible que podamos. Por ejemplo, las expresiones son siempre ms entendibles cuando estn expresadas de forma positiva. As, es aconsejable evitar el uso de NOT en expresiones condicionales. Por ejemplo, no es extrao encontrarnos con cdigo como el siguiente: IF cond1 AND NOT (cond2 OR cond3) THEN proc1; ELSIF cond1 AND (cond2 OR cond3) THEN proc2; ELSIF NOT cond1 AND cond4 THEN proc3; ENDIF; Este cdigo es verdaderamente complicado de entender. Siempre podemos evitar el uso de expresiones negativas en las condiciones para obtener un cdigo mucho ms legible: IF cond1 THEN IF (cond2 OR cond3) THEN proc2; ELSE
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 20 de 41

COM proc1; ENDIF; ELSIF cond4 THEN proc3; ENDIF;

Estndar de Codificacin Oracle

Debemos, sin embargo, encontrar un punto de equilibrio entre la legibilidad del cdigo y la complejidad de las clusulas condicionales ya que demasiadas sentencias condicionales anidadas pueden disminuir la legibilidad del cdigo. Se recomienda un mximo nivel de anidamiento de 4.

3.15.3 Reemplazar sentencias IF con expresiones booleanas


Muchas veces escribimos sentencias condicionales que, aunque vlidas son innecesarias y demasiado voluminosas. Estas sentencias reflejan una falta de entendimientos sobre como debemos usar las expresiones booleanas y las variables. Por ejemplo, podemos encontrarnos con cdigo como el siguiente: DECLARE variable_booleana BOOLEAN; BEGIN IF variable_booleana = TRUE THEN . ELSIF variable_booleana = FALSE THEN ENDIF; que puede ser expresado de la siguiente forma: DECLARE variable_booleana BOOLEAN; BEGIN IF variable_booleana THEN . ELSIF NOT variable_booleana THEN ENDIF; Existen, tambin, ocasiones en las que podemos eliminar las sentencias condicionales. Lo vemos con un ejemplo: IF fecha_contrato < SYSDATE THEN fecha_pasada := TRUE; ELSE fecha_pasada := FALSE; ENDIF; En caso de que estemos seguros de que fecha_pasada es distinto de NULL, podemos sustituir toda la sentencia condicional por: fecha_pasada := fecha_contrado < SYSDATE; O, si no estamos seguros de que fecha_pasada sea distinto de NULL: fecha_pasada := NVL ( fecha_contrado < SYSDATE, FALSE );

3.15.4 Optimizacin de sentencias condicionales


Podemos optimizar la construccin de expresiones condicionales con el objeto de ahorrar tiempo de computacin y acelerar la ejecucin de las aplicaciones. Para ello: Ordenaremos las expresiones lgicas de menos costosas a ms costosas dentro de una sentencia condicional (IF). Esta deja de evaluarse en cuanto una de las expresiones incluidas no es cierta comenzando por la izquierda.
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 21 de 41

COM

Estndar de Codificacin Oracle

En sentencias condicionales compuestas (IF..ELSIF) colocaremos al final ramas con las expresiones ms costosas.

3.16 Control de flujo


3.16.1 No usar sentencias GOTO
Aunque la sentencia GOTO est permitida en el lenguaje PL/SQL su uso debe estar prohibido ya que complica sobremanera el mantenimiento de las aplicaciones.

3.17 No usar sentencias EXECUTE


Aunque la sentencia EXECUTE est permitida en el lenguaje PL/SQL su uso debe estar prohibido ya que complica sobremanera el mantenimiento de las aplicaciones.

3.17.1 Uso de bloques annimos


El lenguaje PL/SQL nos da la posibilidad de crear bloques annimos (BEGIN..END) donde declarar variables, incluir cdigo y manejar excepciones. Su uso ayuda en muchas ocasiones si bien se debe racionalizar para no abusar del mismo en condiciones en las que no son necesarios: No debemos usar los bloques annimos con el mero propsito de agrupar sentencias de cdigo. Si estas sentencias no elevan ninguna excepcin que haya que controlar no es necesario agruparlas en un bloque annimo. Tampoco debemos usar bloques annimos con el objeto de definir variables que tengan una visibilidad reducida y con el objeto de la optimizacin de recursos ya que la existencia de estas variables se reduce al tiempo de ejecucin del cdigo introducido en el bloque. El uso de esta tcnica resta al cdigo de legibilidad y mantenibilidad.

3.18 Bucles
3.18.1 Uso de EXIT y RETURN en bucles WHILE y FOR
Cuando utilizamos las sentencias EXIT y RETURN dentro de un bucle causamos una brusca finalizacin del mismo que hace muy difcil su traza. Por ejemplo, contador := titulos.COUNT; FOR indice IN 1..contador LOOP IF mi_titulo = titulos(indice) THEN RETURN indice; ENDIF; ENDLOOP; RAISE Exit_Function; EXCEPTION WHEN Exit_Function THEN RETURN NULL; Este es un cdigo de mala calidad. Se eleva una excepcin o se encuentra el ttulo y se devuelve el valor en mitad de la seccin ejecutable. Imaginemos que el cuerpo de la funcin contiene 200 lneas de cdigo con diferentes bucles anidados y varias sentencias RETURN repartidas por el mismo. Un caos. Debemos evitar, por tanto, el uso de las sentencias EXIT y RETURN dentro de bucles.

3.18.2 Uso de EXIT en bucles LOOP


Siempre que sea posible se debe condensar toda la lgica de EXIT de los bucles LOOP en una sentencia EXIT (o EXIT WHEN) simple. Lo vemos con un ejemplo:
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 22 de 41

COM LOOP read_line (file1, line1, file1_eof); read_line (file2, line2, file2_eof);

Estndar de Codificacin Oracle

IF (file1_eof AND file2_eof) THEN retval := TRUE; EXIT; ELSIF (line1 != line2) THEN retval := FALSE; EXIT; ELSIF (file1_eof OR file2_eof) THEN retval := FALSE; EXIT; END IF; END LOOP; Podemos reescribir este cdigo condensando la lgica de los EXIT como sigue: LOOP read_line (file1, line1, file1_eof); read_line (file2, line2, file2_eof); IF (file1_eof AND file2_eof) THEN retval := TRUE; exit_loop := TRUE; ELSIF (line1 != line2) THEN retval := FALSE; exit_loop := TRUE; ELSIF (file1_eof OR file2_eof) THEN retval := FALSE; exit_loop := TRUE; END IF; EXIT WHEN exit_loop; END LOOP;

3.18.3 Usar bucles LOOP para evitar el cdigo redundante requerido por los bucles WHILE
Generalmente, usamos bucles LOOP si queremos que el cuerpo del bucle se ejecute, al menos, una vez. Usaremos bucles WHILE si queremos comprobar la condicin antes de que se ejecute el cuerpo. Ya que el bucle WHILE realiza la validacin antes las variables de la expresin condicional deben estar inicializadas. El cdigo para inicializarlas es usualmente el mismo cdigo necesario para realizar la siguiente iteracin. Esta redundancia de cdigo crea un problema al depurar y mantener el cdigo. Los ejemplos ms tpicos son el del incremento de un ndice para recorrer un array o el del clculo de una condicin que acta como guarda para las siguientes iteraciones. Si nos encontramos con esta situacin debemos cambiar el bucle WHILE por un bucle LOOP.

3.18.4 No declarar el ndice para el bucle FOR


PL/SQL ofrece dos clases de bucles FOR: numricos y cursores. Ambos tienen la siguiente forma: FOR indice IN rango LOOP cuerpo END LOOP;

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 23 de 41

COM

Estndar de Codificacin Oracle

El ndice puede ser un entero o un registro. En ambos casos es declarado implcitamente por el runtime de PL/SQL y la visibilidad de la variable ndice est restringida al cuerpo del bucle. Nunca debemos declarar una variable para el ndice del bucle. Si la declaramos estaremos declarando una variable (registro o numrica) completamente separada que, en el mejor de los casos, nunca ser usada o, en el peor de los casos, puede ser usada fuera del bucle de forma que pueda introducir cambios en el comportamiento del mismo.

3.18.5 Recorrer colecciones usando FIRST, LAST y NEXT en bucles


Una coleccin en PL/SQL no es ms que un array unidimensional. Difiere, sin embargo, de un array en que dos de los tres tipos de colecciones (tablas anidadas y tablas indexadas) pueden ser esparcidas. Es decir, que las filas de la coleccin no necesitan estar secuencialmente definidas. Podemos, en otras palabras, asignar un valor a la fila 10 y otro a la fila 100, sin que existan filas entre ambas. Si recorremos una coleccin con un bucle FOR y la coleccin est esparcida, el bucle intentar acceder a filas no definidas y elevar la excepcin NO_DATA_FOUND. Usaremos los mtodos FIRST y NEXT para recorrer hacia delante la coleccin. Usaremos LAST y PRIOR para recorrerla hacia atrs.

3.18.6 Mover expresiones estticas fuera de los bucles y sentencias SQL


Un error comn es el de situar cdigo esttico o no-cambiante en las iteraciones dentro de un bucle. Cuando identifiquemos estas situaciones debemos situar dicho cdigo fuera del bucle asignando su valor a una variable. Referenciaremos dicha variable desde dentro del bucle. Por ejemplo: CREATE OR REPLACE PROCEDURE sumaries_reviews ( summary_title_in IN VARCHAR2, isbn_in IN book.isbn%TYPE) IS CURSOR review_cur IS SELECT text, TO_CHAR (SYSDATE, MM/DD/YYYY) today FROM book_review WHERE isbn = isbn_in; BEGIN FOR review_rec IN review_cur LOOP IF LENGTH( review_rec.text) > 100 THEN review_rec.text := SUBSTR( review_rec.text, 1, 100); END IF; review_pkg.summarize( UPPER(summary_title_in), today, UPPER(review_rec.text) ); END LOOP; END; Existen mltiples problemas en este trozo de cdigo: Si mi cdigo se inicia y finaliza el mismo da no necesito recuperar el SYSDATE en cada iteracin del cursor. Escribimos en el campo text de review_rec. Esto est permitido en PL/SQL, si bien, no debemos modificar la variable ndice del bucle. Si el parmetro summary_title nunca cambia no necesito hacer un UPPER del mismo en cada iteracin. En lugar de comprobar la longitud de review_rec.text y realizar el SUBSTR en cada iteracin, porqu no incluir el SUBSTR dentro de la SELECT?.
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 24 de 41

COM

Estndar de Codificacin Oracle

Este es el mismo cdigo sin los problemas detectados: CREATE OR REPLACE PROCEDURE sumaries_reviews ( summary_title_in IN VARCHAR2, isbn_in IN book.isbn%TYPE) IS l_summary book_types.summary_t := UPPER(summary_title_in); l_today CONSTANT DATE := TRUNC(SYSDATE); CURSOR review_cur IS SELECT UPPER( SUBSTR( text,1, 100) ) text FROM book_review WHERE isbn = isbn_in; BEGIN FOR review_rec IN review_cur LOOP review_pkg.summarize( l_summary, l_today, review_rec.text ); END LOOP; END;

3.19 Uso de datos


3.19.1 Uso de %TYPE y %ROWTIPE para la definicin de variables
Cuando definimos variables basadas en campos de tablas de nuestro modelo de datos debemos utilizar %TYPE y %ROWTYPE como atributos del tipo de datos. Cualquier cambio en el tipo de un campo de una tabla de nuestro modelo de datos requerira la modificacin del cdigo fuente si estos atributos no son usados.

3.19.2 Evitar columnas LONG o LONG RAW


Toda aplicacin debe evitar el uso de este tipo de columnas en la BBDD.

3.19.3 Uso de constantes y parmetros


Es comn encontrarse durante la codificacin con valores (numricos y literales) que se repiten ms de una vez en el cdigo. La prctica ms comn y la ms deseable es la definicin de constantes que definan, a su vez, dichos valores. La modificacin de cualquiera de esos valores ms adelante en la codificacin tendr un pequeo impacto ya que habr que modificar nicamente una lnea de cdigo en lugar de buscar por todo el cdigo de la aplicacin dnde estaba referenciado ese valor para cambiarlo. Es aconsejable, tambin, agrupar la definicin de las constantes en un mismo mdulo de cdigo para su rpida localizacin y una mejor accesibilidad desde el resto de mdulos de cdigo de la aplicacin. En el caso de que los valores constantes puedan cambiar su valor no slo en tiempo de codificacin sino que estos se pueden ver alterados una vez en explotacin, debemos definirlos como parmetros. Para ello, la mejor tcnica es la creacin de una tabla que mapee un cdigo de parmetro con el valor correspondiente. As, si se desea cambiar el valor de un parmetro para que la aplicacin cambie su comportamiento de alguna manera nicamente tendremos que actualizar el valor en la tabla de parmetros que hayamos definido.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 25 de 41

COM

Estndar de Codificacin Oracle

3.20 Acceso a la Base de Datos


3.20.1 Construccin de consultas
3.20.1.1 No usar SELECT *
Cuando realicemos consultas a una o ms tablas de la base de datos debemos evitar el uso del asterisco para la seleccin de todos los campos de la(s) tabla(s). Una modificacin en el modelo de datos puede ocasionar que estas sentencias no funcionen, as como la migracin de la aplicacin a otro entorno donde el orden de las columnas no sea el mismo.

3.20.1.2 Nombres de columnas cualificados


Cuando debemos consultar columnas de varias tablas dentro de una misma consulta es comn encontrarse con columnas de distintas tablas que poseen el mismo nombre. La mejor forma para distinguirlas es anteponerles el nombre de la tabla separado por un punto: <nombre de tabla>.<nombre de columna> Esta tcnica es aconsejable para todas las columnas seleccionadas.

3.20.1.3 Uso de ORDER BY 1,2


PL/SQL nos permite usar en nmero de orden de una columna en la clusula ORDER BY para referenciar dichas columnas. Esta prctica, sin embargo, es altamente desaconsejable debido a la dificultad que conlleva en el mantenimiento. Cualquier cambio en la consulta habra de ser tambin reflejado en la clusula ORDER BY para evitar funcionamientos no deseables en las consultas.

3.20.1.4 Uso del DISTINCT


El uso de la clusula DISTINCT obliga a la sentencia SELECT a devolver filas sin duplicados. La clusula GROUP BY tambin devuelve filas no duplicadas, por tanto, el uso conjunto de DISTINCT y GROUP BY es redundante y obtiene un peor rendimiento.

3.20.1.5 Uso de EXISTS e IN


Existen ocasiones en las que usamos EXISTS o IN para las subconsultas de forma indiscriminada sin fijarnos en cual de las dos clusulas es ms eficiente en cada caso. En caso de que el predicado por el que se filtra est en la subconsulta es ms eficiente el uso de IN. En cualquier otro caso es aconsejable el uso de EXISTS.

3.20.1.6 Uso de NVL


Se recomienda el uso de esta funcin para evitar posibles errores en las querys realizadas. Este NVL se debe emplear siempre y cuando la columna acepte valores nulos.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 26 de 41

COM

Estndar de Codificacin Oracle

3.20.1.7 Uso del carcter comilla


Cuando queremos introducir el carcter comilla simple dentro de una cadena en una consulta es aconsejable el uso de su cdigo ASCII (39) para evitar errores en el parseador de Oracle.

3.20.1.8 Bsquedas por NULL


Las bsquedas por NULL (o NOT NULL) desactivan el uso de ndices y hacen mucho ms costosas las consultas. Por tanto, se ha de evitar el uso de NULL y NOT NULL en las sentencias de consulta. En caso de que el dato por el que se est buscando sean numrico se puede optar por WHERE columna > 0 OR columna < 0. En caso de que el dato sea alfanumrico podemos utilizar la expresin WHERE columna > A% OR columna <= A%.

3.20.1.9 Recomendaciones sobre los ndices


Al igual que las bsquedas por NULL (o NOT NULL) desactivan el uso de ndices todas las funciones aplicadas sobre una columna de indexada deshabilita el ndice, por lo tanto no se recomienda utilizar dichas funciones sobre los ndices. Un ejemplo de estas funciones muy utilizada es la SUBSTR. A la hora de definir un ndice, se recomienda que como mximo el ndice tenga 4 o 5 columnas, de esta manera se intenta evitar los ndices pesados.

3.20.1.10 Uso de ROWNUM


Cuando deseamos limitar el nmero de filas devueltas en una consulta (o cursor) es de gran utilidad el uso de ROWNUM.

3.20.2 Construccin de cursores


3.20.2.1 Declaracin de cursores
El lenguaje PL/SQL proporciona dos mecanismos para el tratamiento de cursores que deben ser usados racionalmente y segn el tratamiento que se quiera hacer del mismo cursor y los datos obtenidos. As, podemos distinguir: CURSOR-FOR-LOOP: Este tipo de declaracin de cursores debe usarse en los casos en los que queramos recorrer todas las filas declaradas en el SELECT del cursor. Las ventajas ms significativas que este ofrece son: de la fila. no es necesario abrir ni cerrar el cursor. no es necesario avanzar el cursor. no es necesario controlar el fin del cursor. no es necesario definir la variable que contendr los valores recogidos

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 27 de 41

COM

Estndar de Codificacin Oracle As, este tipo de bucles aumenta la legibilidad del cdigo ya que necesita mucho menos cdigo de control del propio cursor.

CURSOR-OPEN-FETCH-CLOSE: Este tipo de declaracin de cursores debe usarse en los casos en los que queramos poder interrumpir la lectura de registros en cualquier momento. Este tipo de declaracin de cursores debe ser utilizado siempre seguido de un bucle LOOP. BULK COLLECT INTO Esta opcin permite cargar de forma masiva mltiples registros en una coleccin (aumenta el rendimiento de la operacin)

DECLARE TYPE title_aat IS TABLE OF magazine.title%TYPE INDEX BY BINARY_INTEGER; l_titles title_aat; BEGIN SELECT title BULK COLLECT INTO l_titles FROM magazine; END;

3.20.2.2 Cursores para actualizacin


Nunca debemos usar cursores para actualizacin (FOR UPDATE) a menos que sea estrictamente necesario y, ms an, en aplicaciones on-line. Estos cursores bloquean todas las filas que van a ser actualizadas imposibilitando el acceso a ellas a otras aplicaciones. En caso de que fuese necesario utilizar este tipo de cursores ha de prestarse mucha atencin a la optimizacin del cdigo que gestiona los datos dentro del bucle del cursor para que este consuma el menor tiempo posible y las filas queden liberadas lo antes posible.

3.21 Tamao de los Objetos PL-SQL


Para asegurar una buena legibilidad del cdigo no es aconsejable poner ms de una instruccin por lnea. El lenguaje PL-SQL es un lenguaje estructurado, y se aconseja que cada funcin no sobrepase las 50 lneas de cdigo, en el caso de que sobrepase dicho lmite la aplicacin tiene un problema de anlisis ya que no se ha modularizado las funciones correctamente. Tambin hay que considerar las tablas que se encuentren con ms de 40 columnas definidas, ya que habra que revisar el modelo de datos. Una tabla con ms de 40 columnas se considera que es una tabla poco tratable por el SGDB y el rendimiento de las consultas se vern penalizadas en tiempo ya que la query necesita mucha memoria para almacenar los datos de la tabla.

3.21.1 Objetos sin referenciar


No es aconsejable para el rendimiento y mantenimiento de una aplicacin tener definidos objetos que nos son utilizados. Es muy comn en una aplicacin que ha sufrido varias versiones que tenga procedimientos, tablas, etc.. que no sean referenciadas ya que se utilizaba en una primera versin pero con la evolucin se han quedado inservibles.
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 28 de 41

COM

Estndar de Codificacin Oracle

Para ello, es necesario eliminar estos objetos de modelo de datos y del cdigo, ya sean tabla, funciones o procedimientos de la base de datos.

3.22 Procesos batch


3.22.1 INSERT-SELECT
Para procesar grandes cantidades de informacin, la alternativa al uso de cursores es el movimiento masivo de datos, mediante sentencias CREATE AS SELECT y INSERTSELECT

MENOS EFICIENTE FOR rec IN emp_cur LOOP INSERT INTO my_employee (employee_id,name,salary) VALUES (rec.employee_id,rec.name,rec.salary); END LOOP;

MAS EFICIENTE INSERT /*+ APPEND */ INTO employee_tmp (employee_id,name,salary) SELECT employee_id,name,salary FROM employee;

Esta instruccin realiza un volcado masivo en una tabla del resultado de una consulta. Adems incorporando el hint APPEND (direct-paht insert) logramos eficienciar todava ms la accin del insert. Este hint provoca que la insercin en la tabla, en lugar de buscar huecos vacos y reaprovechar espacio, utilice espacio totalmente nuevo (ahorra el tiempo de buscar huecos vacos)

3.22.2 Eliminacin de ndices y recreacin de ndices


En los procesos de insercin, actualizacin y eliminacin de datos de una tabla, la existencia de ndices sobre columnas afectadas por estas acciones provoca una penalizacin en el rendimiento. En procesos masivos de insercin, actualizacin y elimacin (que afecten a un gran nmero de registros) es ms eficiente eliminar los ndices, realizar la accin masiva, recrear el ndice y actualizar las estadsticas.

3.23 Otros
3.23.1 Usar bloques annimos dentro de sentencias IF para conservar recursos
Una de las caractersticas de PL/SQL es que el desarrollador puede agrupar cualquier conjunto de sentencias dentro de un bloque con su propias secciones de declaracin, ejecutable y excepciones. Si detectamos que un conjunto de operaciones y estructuras de datos no son necesarias a menos que se cumpla una condicin, moveremos todas esas sentencias y estructuras
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 29 de 41

COM

Estndar de Codificacin Oracle

de datos dentro de un bloque annimo dentro, a su vez, de una sentencia condicional. El resultado es que no se cargar la CPU y memoria a menos que sea necesario.

3.23.2 Excepciones
La clusula When-others debe estar presente en todo control de excepciones, as se controla todo tipo de excepciones que se puedan originar a la hora de ejecutar el cdigo.

3.24 Otras reglas a tener en cuenta


No especificar IS NULL o IS NOT NULL en una columna ndice. Si ms del 25% de la tabla va a ser seleccionado no utilizar ndices y utilizar mejor un FULLSCAN. Evita el operador NOT en la clusula WHERE. Usa el operador UNION en lugar de O. Utiliza alias para prefijar el nombre de las columnas. Si dos ndices son de igual prioridad y son usadas en la clusula WHERE, Oracle utilizar el ndice de las columnas especificados ms tarde (es decir el del final). Si dos o ms ndices son de igual rango, podemos forzar un ndice en particular. Concatenando | | a una columna de tipo CHAR y +0 a una columna numrica el ndice no es usado para esa columna. No mezclar tipos de datos. Pues no se utilizan los ndices. Utiliza joins en vez de SELECT anidadas. El orden de los nombres de las tablas en la clusula FROM determina la tabla preferente. Si usamos el optimizador de reglas, si la clusula es ordenada correctamente puede reducirse el nmero de lecturas fsicas. ORACLE toma como tabla preferente la ltima que aparece en la clusula FROM utilizando cualquier ndice disponible en esta tabla y la siguiente tabla preferente ser la penltima, etc. Asegrate que la ltima tabla de la clusula FROM retorna pocos registros con la clusula WHERE. Si se estn transfiriendo datos de una tabla a otra asegrate de que en ambas tablas existe una columna para la fecha de modificacin. Esto asegurar que la transferencia de los cambios que se efectan durante el da ser ms eficiente utilizando un ndice con la fecha de modificacin. Si los datos de las tablas cargadas son creados para tablas temporales, asegrate de que la tabla y los ndices se hayan creado correctamente. Crear los ndices despus de que las filas han sido transferidas a la tabla. Si hay que borrar todos los registros de una tabla es ms rpido hacer un TRUNCATE (con la opcin DROP STORAGE) que hacer un DELETE. Adems con el TRUNCATE podemos liberamos espacio de la tabla (siempre y cuando esta se haya extendido en alguna ocasin), mientras que con el DELETE el espacio sigue siendo ocupado por la tabla (aunque sta est vaca) Asegrate de que no hay muchas sentencias UPDATE sobre una misma tabla. Hay formas de actualizar muchas columnas con una sentencia nica. Si el ndice ya existe concatenado con otra columna, un ndice individual es superfluo. Cuando las columnas son muy grandes, no deberan de ser ndices. Evitar el uso de condiciones 1=1 en construccin de consultas dinmicas (la consulta puede ser susceptible de ser afectada por SQL Injection)

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 30 de 41

COM

Estndar de Codificacin Oracle

3.25 Buenas Prcticas para versiones 10G.

3.25.1 Optimizador basado en costo (CBO)

Conocer el modelo de datos es esencial como, por ejemplo, la relacin entre las entidades de negocios. Este entendimiento va ayudar la escrita de consultas ms eficientes para extraer los datos de mltiplas tablas. En este artigo abordar solamente el optimizador basado en costo (CBO), que fue introducido en la versin 7 del Oracle. El CBO intenta encontrar un plan de ejecucin que posee el menor costo para conectar los datos. Varios costos son calculados y el que presentar el menor costo de ejecucin es escogido. Deben ser colectadas estadsticas peridicamente para determinar un plan de ejecucin ptimo. Pero el CBO es limitado, l no conoce las caractersticas de la aplicacin y tambin no puede entender se la consulta est escrita de la mejor forma. Lo que l hace es intentar encontrar la mejor solucin para su consulta. Y como el CBO asume algunos valores relativos al costo, el plan que fue escogido por l puede no ser necesariamente el mejor plan de ejecucin. Para eso debemos estar siempre listos para optimizar esas consultas, ya que son responsables por 60% de los problemas de desempeo. . Las instrucciones SQL son analizadas por el optimizador Oracle, generando su respectivo plan de acceso. Esas informaciones referentes al anlisis y el propio plan de ejecucin, se quedan disponibles en memoria (SGA) y caso sea ejecutada una nueva instruccin IDNTICA, es realizado el compartimiento del plan de ejecucin ya hecho por el optimizador. Utilice ROWID siempre que posible. Cada lnea almacenada en el Oracle contiene su respectivo ROWID y nunca ser sustituida hasta que sea eliminada. Este ROWID es la direccin fsica del registro. Seleccione en declaraciones selects el ROWID siempre que posible para garantizar el mejor desempeo para sus comandos de update y delete.

Utilice WHERE en lugar de HAVING Evite incluir de forma inadecuada la clusula HAVING dentro de una instruccin SELECT. Having restringe las lneas despus de ellas hubieren sido procesadas. Esto incluye la realizacin de sort, sumarizacin etc

Evite el operador DISTINCT Evite incluir innecesariamente la clusula DISTINCT dentro de una declaracin SELECT. Distinct genera el mtodo de conexin SORT.

Evite select * ...... La columna dinmica * (asterisco) realiza la pesquisa de todas las columnas de las tablas envueltas.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 31 de 41

COM

Estndar de Codificacin Oracle

El optimizador ser obligado a convertir el asterisco para cada columna en la instruccin SELECT, consumiendo recurso. En la mayora de las veces NO necesitamos tener todas las columnas, evitando trfico de red innecesario. Evitar count(*), utilizar count(campo).

Evite utilizar la comparacin is null, porque no utilizar ndice. 7. Dejar las variables usadas para comparacin con campos, exactamente con el mismo tipo de dado. Evitar conversiones implcitas. Evite utilizar outer join. Evite utilizar union, privilegiar union all. Evite negaciones. De privilegio para = y no , utilizar in y no not in. Comprendiendo lo que es selectividad: La selectividad es la primera y ms importante medida del Optimizador Basado en Costo. Ella representa una fraccin de lneas de un conjunto resultante de una tabla o el resultado de un "join" o un "group by". El CBO utiliza estadsticas para determinar la selectividad de un determinado predicado (clusula where o having). La selectividad es directamente ligada al pre dicado de la consulta como ID = 1111, o una combinacin de predicados, como ID = 11111 AND STATUS=Y. El propsito del predicado de una consulta es limitar la propuesta a un nmero de lneas en que estamos interesados. Luego, la selectividad de un predicado indica cuantas lneas de un conjunto sern filtradas por una determinada condicin. La selectividad es igual al nmero de valores distintos que una columna posee.

ndices: Evite funciones en los campos (columnas del banco) indexadas, como substr, concatenacin, conversin implcita, trunc, lower, upper etc. Las funciones tienen por finalidad realizar una conversin sobre determinado contenido. Caso sea utilizada una funcin ORACLE en la clusula WHERE, y su argumento es una columna que contenga el ndice, el optimizador ir descartar el uso del ndice. Procure aplicar la conversin en el lado de la variable y no en el campo del banco. Desarrollado para garantizar mejora de desempeo en la recuperacin de los datos (procesamiento para lecturas). Las posiciones de las columnas en ndices compuestos tienen un importante papel en su utilizacin. Generalmente los ndices ms selectivos son aquellos donde sus columnas contienen una gran cantidad de valores nicos. La utilizacin de un ndice por el optimizador esta directamente asociada a la selectividad de las columnas envueltas en la restriccin de la consulta SQL.

3.25.2 Tablas.
Al momento de disear una tabla tenemos que tener en cuenta los siguientes puntos. Factor de crecimiento: Debemos tener en claro cul ser la carga de la tabla en el tiempo con una visin pesimista. Distribucin de los datos en los discos:
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 32 de 41

COM

Estndar de Codificacin Oracle Para enteder esto debemos conocer como se almacenan las tablas.

3.25.3 Tablespace (espacio de tablas)


Una base de datos se divide en unidades lgicas denominadas TABLESPACES. Un tablespace no es un fichero fsico en el disco, simplemente es el nombre que tiene un conjunto de propiedades de almacenamiento que se aplican a los objetos (tablas, secuencias) que se van a crear en la base de datos bajo el tablespace indicado (tablas, secuencias). Un espacio de tablas puede pertenecer slo a una BD.

Un objeto en base de datos debe estar almacenado obligatoriamente dentro de un tablespace.


Cuando se crea una tabla se debe indicar el espacio de tablas al que se destina. Por defecto se depositan en el espacio de tablas SYSTEM Las propiedades que se asocian a un tablespace son: Localizacin de los ficheros de datos. Especificacin de mximas cuotas de consumo de disco. Control de la disponibilidad de los datos (en lnea o fuera de lnea). Backup de datos.

Cuando un objeto se crea dentro de un cierto tablespace, este objeto adquiere todas las propiedades antes descritas del tablespace utilizado.

En este esquema podemos ver que, por ejemplo, la tabla ARTICULO se almacena dentro del tablespace A, y que por lo tanto tendr todas las propiedades del tablespace A que pueden ser:
Archivo: 178900375.doc.ms_office 2005 - everis Pgina 33 de 41

COM

Estndar de Codificacin Oracle

Sus ficheros de datos estn en $ORACLE_HOME/datos/datos_tablespace_A Los objetos no pueden ocupar ms de 10Mb de espacio de base de datos.

-En cualquier momento se puede poner fuera de lnea todos los objetos de un cierto tablespace. -Se pueden hacer copiar de seguridad slo de ciertos tablespaces. Si nos fijamos, se puede apreciar que es posible tener una tabla en un tablespace, y los ndices de esa tabla en otro. Esto es debido a que los ndices no son ms que objetos independientes dentro de la base de datos, como lo son las tablas. Y al ser objetos independientes, pueden ir en tablespaces independientes. En l Tablespace SYSTEM se almacenan todos los datos de sistema, el catlogo y todo el cdigo fuente y compilado de procedimientos PL/SQL. Tambin es posible utilizar el mismo tablespace para guardar datos de usuario. En el esquema tambin vemos que hay un tablespace Temporal (en gris oscuro). Este representa las propiedades que tendrn los objetos que la base de datos cree temporalmente para sus clculos internos (normalmente para ordenaciones y agrupaciones). Su creacin difiere en una de sus clusulas de creacin. El tablespace RO (en gris claro) difiere de los dems en que es de solo lectura (Read Only), y que por lo tanto todos los objetos en l contenidos pueden recibir rdenes de consulta de datos, pero no de modificacin de datos. Estos puede residir en soportes de slo lectura, como pueden ser CDROMs, DVDs, etc. Cuando se crea un tablespace, ste se crea de lectura/escritura. Despus se puede modificar para que sea de solo lectura. Un tablespace puede estar en lnea o fuera de ella (Online o OffLine), esto es que todos los objetos contenidos en l estn a disposicin de los usuarios o estn inhabilitados para restringir su uso. Cualquier objeto almacenado dentro de un tablespace no podr ser accedido si este est fuera de lnea.

Se pueden ver los espacios de tablas definidos en nuestra BD con el comando SQL siguiente:

SQL> select * from user_tablespaces; Como Crear un tablespace Para Crear un tablespace
CREATE TABLESPACE nombreTableSpace DATAFILE 'nombreDataFile.dbf' size 100M;

Para Modificar un tableSpace


Alter tablespace prueba add datafile'/users/oradata/orcl/prueba02.dbf' size 50M;

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 34 de 41

COM

Estndar de Codificacin Oracle

3.25.4 Concepto de Datafile (fichero de datos)


Un datafile es la representacin fsica de un tablespace. Son los "ficheros de datos" donde se almacena la informacin fsicamente. Un datafile puede tener cualquier nombre y extensin (siempre dentro de las limitaciones del sistema operativo), y puede estar localizado en cualquier directorio del disco duro, aunque su localizacin tpica suele ser

$ORACLE_HOME/Database. Un datafile tiene un tamao predefinido en su creacin (por ejemplo 100Mb) y este puede ser alterado en cualquier momento. Cuando creemos un datafile, este ocupar tanto espacio en disco como hayamos indicado en su creacin, aunque internamente est vaco. Oracle hace esto para reservar espacio continuo en disco y evitar as la fragmentacin. Conforme se vayan creando objetos en ese tablespace, se ir ocupando el espacio que cre inicialmente. Un datafile est asociado a un solo tablespace y, a su vez, un tablespace est asociado a uno o varios datafiles. Es decir, la relacin lgica entre tablespaces y datafiles es de 1-N, maestro-detalle.

En el esquema podemos ver como el Tablespace A est compuesto (fsicamente) por tres datafiles (DATOS_1.ORA, DATOS_2.ORA y DATOS_3.ORA). Estos tres datafiles son los ficheros fsicos que soportan los objetos contenidos dentro del tablespace A. Aunque siempre se dice que los objetos estn dentro del tablespace, en realidad las tablas estn dentro del datafile, pero tienen la propiedades asociadas al tablespace. Cada uno de los datafiles utilizados est ocupando su tamao en disco (50 Mb los dos primeros y 25 Mb el ltimo) aunque en realidad slo contengan dos objetos y estos objetos no llenen el espacio que est asignado para los datafiles.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 35 de 41

COM

Estndar de Codificacin Oracle

Los datafiles tienen una propiedad llamada AUTOEXTEND, que se si est activa, se encarga de que el datafile crezca automticamente (segn un tamao indicado) cada vez que se necesite espacio y no exista. Al igual que los tablespaces, los datafiles tambin puede estar en lnea o fuera de ella.

3.25.5 Concepto de Segment (segmento, trozo, seccin)


Un segment es aquel espacio reservado por la base de datos, dentro de un datafile, para ser utilizado por un solo objeto. As una tabla (o cualquier otro objeto) est dentro de su segmento, y nunca podr salir de l, ya que si la tabla crece, el segmento tambin crece con ella. Fsicamente, todo objeto en base de datos no es ms que un segmento (segmento, trozo, seccin) dentro de un datafile. Se puede decir que, un segmento es a un objeto de base de datos, lo que un datafile a un tablespace: el segmento es la representacin fsica del objeto en base de datos (el objeto no es ms que una definicin lgica).

Podemos ver cmo el espacio que realmente se ocupa dentro del datafile es el segment y que cada segmento pertenece a un objeto. Existen 5 tipos de segmentos: De datos: almacenan las tablas. De ndices: permiten un acceso rpido a los datos dependiendo de la cantidad de los mismos (rboles B). Las consultas que slo referencian a columnas indexadas se resuelven en el ndice. Establecen un control de unicidad (los ndices son automticos cuando se definen claves primarias). Cada ndice ocupa un segmento independiente del segmento de datos y deberan estar en un espacio de tablas distinto al de los datos, para mejorar el rendimiento. De rollback: son objetos internos de la BD que permiten efectuar la restauracin de las transacciones no validadas asegurando la consistencia en lectura. La estructura de los registros de rollback es : o Identificador de la transaccin. o Direccin del bloque donde est la tabla.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 36 de 41

COM o o o

Estndar de Codificacin Oracle

Nmero de fila. Nmero de columna. Valor del dato antiguo (antes de ser modificado).

Son tan importantes que una BD no puede arrancar si no puede acceder al menos a un segmento de rollback. Si la BD tiene mltiples espacios de tablas, deben existir al menos dos segmentos de rollback y cada segmento de rollback debe tener al menos dos extensiones, reutilizables de manera cclica. Esto segmentos son un objeto compartido de la BD, aunque se puede asinar un segmento de rollback particular a una transaccin dada. Temporales: son creados por Oracle para un uso temporal cuando debe realizar una ordenacin que no le cabe en memoria, y en las operaciones: create index, order by, group by, distinct, union, intersect, minus. Son eliminados cuando la sentencia finaliza. De bootstrap: Se crea en SYSTEM y contiene definiciones del diccionario para sus tablas, que se cargan al abrir la BD. No requiere ninguna accin por parte del DBA. No cambia de tamao.

La tabla que guarda la informacin de los segmentos de usuario es user_segments, y se puede visualizar la informacin sobre los segmentos con la sentencia SQL siguiente:

SQL> select * from user_segments;

3.25.6 Concepto de Extent (extensin)


Para cualquier objeto de base de datos que tenga cierta ocupacin en disco, es decir, cualquier objeto que tenga un segment relacionado, existe el concepto de extent. Extent es un espacio de disco que se reserva de una sola vez, un segmento que se reserva en un momento determinado de tiempo. El concepto de extent es un concepto fsico, unos estn separados de otros dentro del disco. Ya dijimos que todo objeto tiene su segmento asociado, pero lo que no dijimos es que este segmento, a su vez, se compone de distintas extensiones. Un segmento, puede ser reservado de una sola vez (10 Mb de golpe), o de varias veces (5 Mb hoy y 5 Mb maana). Cada una de las veces que se reserva espacio se denomina extensin.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 37 de 41

COM

Estndar de Codificacin Oracle

En el esquema vemos como el objeto (tabla) FACTURA tiene un segmento en el datafile A-1, y este segmento est compuesto de 3 extensiones. Una de estas extensiones tiene un color distinto. Esto es porque existen dos tipos de extensiones: INITIAL (extensiones iniciales): estas son las extensiones que se reservan durante la creacin del objeto. Una vez que un objeto est creado, no se puede modificar su extensin inicial. NEXT (siguientes o subsiguientes extensiones): toda extensin reservada despus de la creacin del objeto. Si el INITIAL EXTENT de una tabla est llena y se est intentando insertar ms filas, se intentar crear un NEXT EXTENT (siempre y cuando el datafile tenga espacio libre y tengamos cuota de ocupacin suficiente). Sabiendo que las extensiones se crean en momentos distintos de tiempo, es lgico pensar que unas extensiones pueden estar fragmentadas de otras. Un objeto de base de datos no reside todo junto dentro del bloque, sino que residir en tantos bloque como extensiones tenga. Por eso es crtico definir un buen tamao de extensin inicial, ya que, si es lo suficientemente grande, el objeto nunca estar fragmentado. Si el objeto tiene muchas extensiones y stas estn muy separadas en disco, las consultas pueden retardarse considerablemente, ya que las cabezas lectoras tienes que dar saltos constantemente. El tamao de las extensiones (tanto las INITIAL como las NEXT), se definen durante la creacin del objeto y no puede ser modificado despus de la creacin. Oracle recomienda que el tamao del INITIAL EXTENT sea igual al tamao del NEXT EXTENT. La mejor solucin es calcular el tamao que tendr el objeto (tabla o ndice), multiplicando el tamao de cada fila por una estimacin del nmero de filas. Cuando hemos hecho este clculo, debemos utilizar este tamao como extensin INITIAL y NEXT, y tendremos prcticamente la certeza de que no se va a producir fragmentacin en ese objeto. En caso de detectar ms de 10 extensiones en un objeto (consultando el catlogo de Oracle, como veremos), debemos recrear el objeto desde cero (aplicando el clculo anterior) e importar de nuevo los datos. Ciertas operaciones, necesitan de espacio en disco para poder realizarse. El espacio reservado se denomina segmentos temporales. Se pueden crear segmentos temporales cuando: Se crea un ndice Se utiliza ORDER BY, DISTINTC o GROUP BY en un SELECT.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 38 de 41

COM

Estndar de Codificacin Oracle

Se utilizan los operadores UNION, INTERSECT o MINUS. Se utilizan joins entre tablas. Se utilizan subconsultas.

3.25.7 Concepto de Data block (bloque de datos)


Un data block es el ltimo eslabn dentro de la cadena de almacenamiento. El concepto de Data block es un concepto fsico, ya que representa la mnima unidad de almacenamiento que es capaz de manejar Oracle. Igual que la mnima unidad de almacenamiento de un disco duro es la unidad de asignacin, la mnima unidad de almacenamiento de Oracle es el data block. En un disco duro no es posible que un fichero pequeo ocupe menos de lo que indique la unidad de asignacin, as si la unidad de asignacin es de 4 Kb, un fichero que ocupe 1 Kb, en realidad ocupa 4 Kb. Siguiendo con la cadena, cada segmento (o cada extensin) se almacena en uno o varios bloques de datos, dependiendo del tamao definido para el extensin, y del tamao definido para el data block.

(*) Espacio ocupado en el data block por la primera NEXT EXTENSION. (#) Espacio ocupado en unidades de asignacin del sistema operativo por los data blocks anteriores. El esquema muestra toda la cadena de almacenamiento de Oracle.

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 39 de 41

COM

Estndar de Codificacin Oracle

Desde el nivel ms fsico al ms lgico: Unidades de asignacin del sistema operativo (El ms fsico. No depende de Oracle) Data blocks de Oracle Extents Segments DataFiles Tablespaces (El ms lgico) El tamao de las unidades de asignacin del sistema operativo se define durante el particionado del disco duro (FDISK, FIPS), y el espacio de los data blocks de Oracle se define durante la instalacin y no puede ser cambiado. Como es lgico, el tamao de un data block tiene que ser mltiplo del tamao de una unidad de asignacin, es decir, si cada unidad de asignacin ocupa 4 K, los data blocks pueden ser de 4K, 8K, 12K para que en el sistema operativo ocupen 1, 2, 3 unidades de asignacin. Esquema extrado del Oracle8 Concepts

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 40 de 41

COM

Estndar de Codificacin Oracle

4. Referencias bibliogrficas
Oracle 8 Concepts (Oracle Corporation) Oracle 8 Sql Referente (Oracle Corporation) Oracle 8 Tuning (Oracle Corporation) Documento de Apoyo Arquitectura Oracle (everis) Documento de Apoyo ndices Oracle (everis) Documento de Apoyo Vista Oracle (everis) Documento de Apoyo Definicin de Estndares (everis)

Documentacin Documentacin Documentacin Apoyo ndices Oracle Apoyo v1.0.doc Vistas Oracle v1.0.doc Apoyo Arquitectura Oracle v1.0.doc

Documentacin Apoyo Definicin Estndares v1.0.doc

Archivo: 178900375.doc.ms_office 2005 - everis Pgina 41 de 41