Вы находитесь на странице: 1из 14

MIGRACION A ORACLE 11G

R2

CAMBIOS DE FUNCIONAMIENTO RESPECTO A VERSION 10g


1) Envo de correos

Para habilitar el envo de correos hay que activar las listas de control (ACL) para el
usuario GESAFIN, ya que se va a utilizar el paquete PKG_GESAFIN_NOTIFICACIONES:
BEGIN
DBMS_NETWORK_ACL_ADMIN.create_acl (
acl
=> 'acl_gesafin.xml',
description => 'A test of the ACL functionality',
principal
=> 'GESAFIN',
is_grant
=> TRUE,
privilege
=> 'connect',
start_date
=> SYSTIMESTAMP,
end_date
=> NULL);
COMMIT;
END;
/
BEGIN
DBMS_NETWORK_ACL_ADMIN.assign_acl (
acl
=> 'acl_gesafin.xml',
host
=> '*.lico.com',
lower_port => NULL,
upper_port => NULL);
COMMIT;
END;

Se puede comprobar que se ha creado correctamente con la siguiente query:


11gR2.explotacion>
SELECT acl,
2
principal,
3
privilege,
4
is_grant,
5
TO_CHAR(start_date, 'DD/MM/YYYY') AS start_date,
6
TO_CHAR(end_date,
'DD/MM/YYYY') AS end_date
7 FROM
dba_network_acl_privileges;
ACL
PRINCIPAL PRIVILE IS_GRANT
START_DATE END_DATE
--------------------------- ---------- ------- ------------- ---------- ---------/sys/acls/acl_gesafin.xml
GESAFIN
connect true
07/02/2011
1 fila seleccionada.

2) Indices de funcin

Cuando se crea un ndice de funcin (FBI) con la sentencia decode(), si la columna


usada en de tipo number o date, Oracle la convierte a char, y aade
automticamente el formato de fecha con das, horas, minutos y segundos para date:
11gR2.explotacion>
create table prueba (c1 varchar2(5), c2 number(1), c3 date);
Tabla creada.
11gR2.explotacion>
create index prueba_idx_1 on prueba(decode(c1,null,'NULO',null));
ndice creado.
11gR2.explotacion>
create index prueba_idx_2 on prueba(decode(c2,null,'NULO',null));
ndice creado.
11gR2.explotacion>
create index prueba_idx_3 on prueba(decode(c3,null,'NULO',null));
ndice creado.
11gR2.explotacion>
select index_name,column_expression
2
from all_ind_expressions
3
where index_owner = 'EXPLOTACION'
4
and table_name = 'PRUEBA';
INDEX_NAME
COLUMN_EXPRESSION
----------------- ---------------------------------------------------------------PRUEBA_IDX_1
DECODE("C1",NULL,'NULO',NULL)
PRUEBA_IDX_2
DECODE(TO_CHAR("C2"),NULL,'NULO',NULL)
PRUEBA_IDX_3
DECODE(TO_CHAR("C3",'dd/mm/yyyy hh24:mi:ss'),NULL,'NULO',NULL)
3 filas seleccionadas.

Es importante tener esto en cuenta y respetar la sintxis en las consultas o el


optimizador de Oracle no ser capaz de usar el ndice:
select * from prueba where decode(c3,null,'NULO',null) = 'NULO'
Plan hash value: 2685886336
----------------------------------------------------------------| Id | Operation
| Name |Cost(%CPU)| A-Time
|Buffers|
----------------------------------------------------------------| 0 |SELECT STATEMENT |
|
3 (100)|00:00:00.01|
7 |
|* 1 | TABLE ACCESS FULL| PRUEBA |
3
(0)|00:00:00.01|
7 |
----------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------1 - filter(DECODE(INTERNAL_FUNCTION("C3"),NULL,'NULO',NULL)='NULO')

select * from prueba where


decode(to_char(c3,'dd/mm/yyyy hh24:mi:ss'),null,'NULO',null) = 'NULO'
Plan hash value: 1199035738
--------------------------------------------------------------------------------| Id | Operation
| Name
|Cost(%CPU)|
A-Time |Buffers|
--------------------------------------------------------------------------------| 0 |SELECT STATEMENT
|
|
2 (100)|00:00:00.01|
2 |
| 1 | TABLE ACCESS BY INDEX ROWID| PRUEBA
|
2
(0)|00:00:00.01|
2 |
|* 2 | INDEX RANGE SCAN
| PRUEBA_IDX_3 |
1
(0)|00:00:00.01|
1 |
--------------------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2 - access("PRUEBA"."SYS_NC00006$"='NULO')

Hay 2 posibles soluciones a este comportamiento:


1) Utilizar sintaxis reducida para el formato fecha
El ndice de funcin puede crearse como:
create index prueba_idx_3
on prueba(decode(to_char(c3,'dd/mm/yyyy'),null,'NULO',null));

En este caso la sintaxis a utilizar en las consultas sera la misma:


select * from prueba where
decode(to_char(c3,'dd/mm/yyyy'),null,'NULO',null) = 'NULO'

2) Utilizar columnas virtuales


En Oracle 11gR2 existe una nueva funcionalidad llamada columna virtual.
Esta funcionalidad permite crear una nueva columna a la tabla basada en
una frmula o funcin, esta nueva columna no ocupa espacio fsico y slo es
calculada cuando es utilizada en alguna consulta.
As pues, a la tabla del ejemplo se le podra aadir una columna virtual con
la funcin decode(), y crear el ndice sobre dicha columna, de este modo en
las consultas slo tiene que hacerse referencia a la nueva columna virtual,
evitando la sintaxis compleja que puede dar lugar a problemas de
rendimiento:
alter table prueba add (c3_null as
(DECODE(TO_CHAR(C3,'dd/mm/yyyy'),NULL,'NULO',NULL)));
create index prueba_idx4 on prueba(c3_null);
select * from prueba

where c3_null = 'NULO'

Plan hash value: 1362388461


--------------------------------------------------------------------| Id | Operation
| Name
|Cost(%CPU)|Buffers |
--------------------------------------------------------------------| 0 |SELECT STATEMENT
|
|
1 (100)|
2 |
| 1 | TABLE ACCESS BY INDEX ROWID| PRUEBA
|
1
(0)|
2 |
|* 2 | INDEX RANGE SCAN
| PRUEBA_IDX4 |
1
(0)|
1 |
--------------------------------------------------------------------Predicate Information (identified by operation id):
--------------------------------------------------2 - access("C3_NULL"='NULO')

NOTA: hay creada una incidencia (201100060) sobre este aspecto para modificar los
ndices que se ven afectados antes de realizar la migracin a la versin 11gR2, de
esta forma al cambiar a la nueva versin no ser necesario modificar nada.

3) Tablas IOT y segmentos de datos Overflow

Cuando se crea una tabla IOT (Index-Organized Table) en la versin 11gR2, si el


tamao mximo de la fila (en funcin del nmero de campos y el tamao de los
mismos) excede el 50% del tamao del bloque del ndice, es necesario crear dicha
tabla con un segmento de datos overflow o la sentencia Create fallar con el
siguiente error:
ORA-01429: Index-Organized Table: no data segment to store overflow row-pieces
11gR2.explotacion>
CREATE TABLE EXPLOTACION.DATOS_PRUEBAS_11G
2
(
CODIGODEEMPRESA VARCHAR2(6),
3
TIPODENEGOCIO VARCHAR2(1),
4
CODIGODEINFORME VARCHAR2(30),
5
DESCRIPCION VARCHAR2(40),
6
MEDIODEENVIO VARCHAR2(1),
7
ASUNTO VARCHAR2(40),
8
MODODEENVIO VARCHAR2(1),
9
COMENTARIO1 VARCHAR2(300),
10
COMENTARIO2 VARCHAR2(300),
11
COMENTARIO3 VARCHAR2(300),
12
NOMRESPONSABLE VARCHAR2(60),
13
TELRESPONSABLE VARCHAR2(15),
14
FAXRESPONSABLE VARCHAR2(15),
15
CONSTRAINT CLAVEPORTADAS PRIMARY KEY (CODIGODEEMPRESA, TIPODENEGOCIO,
CODIGODEINFORME) ENABLE
16
) ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
17
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
18
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
19
TABLESPACE INDX PCTTHRESHOLD 50;
CREATE TABLE EXPLOTACION.DATOS_PRUEBAS_11G
*
ERROR en lnea 1:
ORA-01429: Tabla organizada por ndices: no hay ningn segmento de datos para
almacenar las partes de filas desbordadas
11gR2.explotacion>
CREATE TABLE EXPLOTACION.DATOS_PRUEBAS_11G
2
(
CODIGODEEMPRESA VARCHAR2(6),
3
TIPODENEGOCIO VARCHAR2(1),
4
CODIGODEINFORME VARCHAR2(30),
5
DESCRIPCION VARCHAR2(40),
6
MEDIODEENVIO VARCHAR2(1),
7
ASUNTO VARCHAR2(40),
8
MODODEENVIO VARCHAR2(1),
9
COMENTARIO1 VARCHAR2(300),
10
COMENTARIO2 VARCHAR2(300),
11
COMENTARIO3 VARCHAR2(300),
12
NOMRESPONSABLE VARCHAR2(60),
13
TELRESPONSABLE VARCHAR2(15),
14
FAXRESPONSABLE VARCHAR2(15),
15
CONSTRAINT CLAVEPORTADAS PRIMARY KEY (CODIGODEEMPRESA, TIPODENEGOCIO,
CODIGODEINFORME) ENABLE
16
) ORGANIZATION INDEX NOCOMPRESS PCTFREE 10 INITRANS 2 MAXTRANS 255 LOGGING
17
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
18
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)
19
TABLESPACE INDX PCTTHRESHOLD 50
20
OVERFLOW TABLESPACE INDX;
Tabla creada.

NOTA: hay creada una incidencia (201100152) sobre este aspecto para modificar las
tablas IOT que se ven afectados antes de realizar la migracin a la versin 11gR2, de
esta forma al cambiar a la nueva versin no ser necesario modificar nada.

4) Juego de caracteres de DB (NLS_CHARACTERSET) AL32UTF8

Al instalar la DB Oracle 11gR2, el juego de caracteres a utilizar ser AL32UTF8. Sus


caractersticas principales son:
Incluye la versin UNICODE 5.0
Acepta todos los conjuntos de caracteres
Los campos varchar2 ocupan de 1 a 3 bytes por caracter
Los caracteres suplementarios se almacenan utilizando 4 bytes por caracter
En relacin al juego de caracteres, en la DB se establecer el parametro
nls_length_semantics al valor CHAR:
11gR2.explotacion>
show parameter semantic
NAME_COL_PLUS_SHOW_PARAM
TYPE
VALUE_COL_PLUS_SHOW_PARAM
-------------------------------------------- ----------- ------------------------nls_length_semantics
string
CHAR

Con esta configuracin, los campos varchar2 de las tablas podrn almacenar un
mximo de 4000 caracteres siempre que stos pertenezcan al lenguaje estndar y se
almacenen en 1 slo byte por caracter; si la fila contiene caracteres especiales o
suplementarios (como o ), el nmero mximo de caracteres se reducir:
11gR2.explotacion>
create table t_prueba (c1 varchar2(4000));
Tabla creada.
11gR2.explotacion>
@ddl t_prueba
Procedimiento PL/SQL terminado correctamente.
DDL
------------------------------------------------------------------------------------CREATE TABLE "EXPLOTACION"."T_PRUEBA"
(
"C1" VARCHAR2(4000 CHAR)
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS NOLOGGING
TABLESPACE "EXPLOTACION" ;
1 fila seleccionada.
11gR2.explotacion> --> 4000 caracteres normales: OK
insert into t_prueba values (rpad(' ',3999,'*') || '*');
1 fila creada.
11gR2.explotacion> --> 4001 caracteres normales: ERROR
insert into t_prueba values (rpad(' ',3999,'*') || '**');
insert into t_prueba values (rpad(' ',3999,'*') || '**')
*
ERROR en lnea 1:
ORA-01489: resultado de la concatenacin de cadena de caracteres demasiado largo
11gR2.explotacion> --> 3999 caracteres normales + 1 caracter ampliado: ERROR
insert into t_prueba values (rpad(' ',3999,'*') || '');
insert into t_prueba values (rpad(' ',3999,'*') || '')
*
ERROR en lnea 1:
ORA-01489: resultado de la concatenacin de cadena de caracteres demasiado largo

RENDIMIENTO RESPECTO A VERSION 10g


EXPLOTACION
1) Nuevos procesos background

La versin 11gR2 aade nuevos procesos background a los ya existentes en la versin


10g, lo que supone un consumo ms elevado de CPU.
2) RMAN gestiona mejor el Backup de UNDO

RMAN no realiza backup de los datos de UNDO que han sido validados (committed y
expired) y, por tanto, no son necesarios para la restauracin, RMAN slo realiza
backup de unos pocos bloques del tablespace de UNDO (uncommitted).
Esta caracterstica reduce el tamao de las copias de seguridad, disminuyendo
tambin el tiempo de realizacin del Backup (as como de la restauracin en caso de
ser necesaria), y est implementado de forma automtica en la versin 11g.
3) Realizar backup de metadatos ASM

La instancia ASM mantiene sus metadatos (nombre de los grupos de discos, nombre
de cada disco que forma un grupo, estructura de directorios, ) en las propias
cabeceras de los discos. As, si por cualquier circunstancia se perdiera
completamente un grupo de discos, la restauracin puede ser bastante compleja.
Oracle 11g incorpora nuevos comandos para trabajar con ASM (con la utilidad
asmcmd) que permiten realizar un backup de los metadatos y restaurarlos si fuera
necesario:
bash-3.00$ export ORACLE_SID=+ASM
bash-3.00$ export ORACLE_HOME=/opt/oracle/11.2.0/grid
bash-3.00$ $ORACLE_HOME/bin/asmcmd
ASMCMD> ls
GORACLE/
ASMCMD> cd GORACLE/PRODUCA
ASMCMD> ls
CONTROLFILE/
DATAFILE/
ONLINELOG/
PARAMETERFILE/
TEMPFILE/
spfilePRODUCA.ora
ASMCMD> md_backup -G GORACLE /Backup/asm_metadata.bck
Disk group metadata to be backed up: GORACLE
Current alias directory path: PRODUCA/TEMPFILE
Current alias directory path: PRODUCA/DATAFILE
Current alias directory path: PRODUCA/ONLINELOG
Current alias directory path: PRODUCA
Current alias directory path: PRODUCA/PARAMETERFILE
Current alias directory path: PRODUCA/CONTROLFILE
ASMCMD> md_restore /Backup/asm_metadata.bck -S /Backup/asm_metadata.sql
Current Diskgroup metadata being restored: GORACLE
ASMCMD> exit
bash-3.00$ ls -lah /Backup/asm_metadata.*
-rw-r--r-1 oracle
oinstall
21K mar 11 09:51 /Backup/asm_metadata.bck
-rw-r--r-1 oracle
oinstall
10K mar 11 09:53 /Backup/asm_metadata.sql
bash-3.00$ more /Backup/asm_metadata.sql
create diskgroup GORACLE NORMAL redundancy failgroup GFAIL_01 disk
'/dev/rdsk/c3t600508B4001075F00001000003470000d0s6' name DISK_003
size 51152M , '/dev/rdsk/c3t600508B40010555F0000D00012F10000d0s6' name DISK_001 size 51152M
failgroup GFAIL_02 disk '/dev/rdsk/c3t6
00508B40010555F0000D000130F0000d0s6' name DISK_002 size 51152M ,
'/dev/rdsk/c3t600508B4001075F000010000034A0000d0s6' name DISK_004 s
ize 51152M attribute 'compatible.asm' = '11.2.0.0.0' , 'compatible.rdbms' = '10.1.0.0.0' ,
'au_size' = '1048576', 'sector_size' = '5

12', 'cell.smart_scan_capable' = 'FALSE';


alter diskgroup /*ASMCMD AMBR*/GORACLE set attribute 'TEMPLATE.OCRBACKUP.REDUNDANCY' = '18';
[...]
alter
alter
alter
alter
alter
alter

diskgroup
diskgroup
diskgroup
diskgroup
diskgroup
diskgroup

/*ASMCMD
/*ASMCMD
/*ASMCMD
/*ASMCMD
/*ASMCMD
/*ASMCMD

AMBR
AMBR
AMBR
AMBR
AMBR
AMBR

*/
*/
*/
*/
*/
*/

GORACLE
GORACLE
GORACLE
GORACLE
GORACLE
GORACLE

add
add
add
add
add
add

directory
directory
directory
directory
directory
directory

'+GORACLE/PRODUCA';
'+GORACLE/PRODUCA/DATAFILE';
'+GORACLE/PRODUCA/PARAMETERFILE';
'+GORACLE/PRODUCA/ONLINELOG';
'+GORACLE/PRODUCA/TEMPFILE';
'+GORACLE/PRODUCA/CONTROLFILE';

Con el comando md_backup creamos un backup de los metadatos del grupo de


discos, y con md_restore podemos crear un script para generar el cdigo para recrear
la estructura original en caso de prdida, lo que facilita bastante las tareas de
recuperacin de datos posteriores.
4) Deteccin de bloques corruptos desde Rman

La utilidad Rman incorpora el comando validate database, que chequea la Base de


Datos en busca la posible existencia de bloques corruptos.
Si al ejecutar el comando se encuentran bloques corruptos en algn datafile, Rman
genera un fichero de trazas con la informacin obtenida y crea una lista de bloques
corruptos, que pueden ser directamente recuperados desde la ltima copia de
seguridad con un solo paso, gracias al comando recover corruption list:
RMAN> validate database;
Iniciando validate en 14/03/2011 16:37:38
canal asignado: ORA_DISK_1
canal ORA_DISK_1: SID=136 tipo de dispositivo=DISK
canal ORA_DISK_1: iniciando validacin del archivo de datos
canal ORA_DISK_1: especificando archivo(s) de datos para validacin
[...]
Estado de Archivo Bloques Vacos Marcados como Corruptos Bloques Examinados SCN Superior
---- ------ -------------- ------------ --------------- ---------7
FAILED 0
0
256
1463601
Nombre de Archivo: /oradisk/Backup/Export/ts_prueba.dbf
Tipo de Bloque Bloques con Fallos Bloques Procesados
-------------- ------------------ -----------------Datos
1
1
ndice
0
0
Otros
125
255
la validacin ha encontrado uno o ms bloques corruptos
Consulte el archivo de rastreo /trace/ORA10_ora_8980.trc para obtener ms informacin
canal ORA_DISK_1: iniciando validacin del archivo de datos
canal ORA_DISK_1: especificando archivo(s) de datos para validacin
[...]
canal ORA_DISK_1: iniciando validacin del archivo de datos
canal ORA_DISK_1: especificando archivo(s) de datos para validacin
incluyendo el archivo de control actual para validacin
incluyendo SPFILE actual en el juego de copias de seguridad
canal ORA_DISK_1: validacin terminada, tiempo transcurrido: 00:00:01
Lista de Archivos de Control y SPFILE
===============================
Tipo de Archivo
Estado Bloques con Fallos Bloques Examinados
------------------ ------ ------------------ -----------------SPFILE
OK
0
2
Archivo de Control OK
0
594
validate terminado en 14/03/2011 16:40:23
RMAN> recover corruption list;
Iniciando recover en 14/03/2011 16:40:50
usando el canal ORA_DISK_1
canal ORA_MAINT_DISK_1: restaurando bloque(s)
canal ORA_MAINT_DISK_1: especificando bloque(s) para restaurar del juego de copias de seguridad

restaurando bloques del archivo de datos 00007


canal ORA_MAINT_DISK_1: leyendo desde la parte de copia de seguridad
/Backup/Rman/Ora10_b_p3m77ahq_1_1
canal ORA_MAINT_DISK_1: manejador de parte=/Backup/Rman/Ora10_b_p3m77ahq_1_1
etiqueta=BCK_RMAN_DIARIO
canal ORA_MAINT_DISK_1: bloques restaurados de la parte de copia de seguridad 1
canal ORA_MAINT_DISK_1: restauracin de bloque terminada, tiempo transcurrido: 00:00:03
iniciando la recuperacin del medio fsico
recuperacin del medio fsico terminada, tiempo transcurrido: 00:00:03
recover terminado en 14/03/2011 16:40:59

5) Mejor gestin de dependencias en paquetera

Al modificar un paquete, funcin o procedimiento, Oracle internamente hace una


mejor gestin de los mtodos con dependencias, lo que se traduce en menos
paquetera con estado INVALID para recompilar.
6) Compilar paquetera en modo nativo

La compilacin nativa existe desde la versin 9i, permitiendo la ejecucin de cdigo


PL/SQL de forma mucho ms rpida que con la compilacin interpretada (por
defecto en Oracle). Pero a diferencia de versiones anteriores, en Oracle 11g no es
necesario instalar un compilador de C en el servidor ni definir una librera donde se
creen los ficheros del S.O. intermedios.
Los beneficios de la compilacin nativa se obtienen simplemente con la modificacin
de un parmetro dinmico:
11gR2.explotacion>
alter system set plsql_code_type='NATIVE' scope=BOTH;
Sesin modificada.

La nica desventaja de la compilacin nativa radica en un mayor tiempo de


compilacin de la paquetera, por eso debe aplicarse solo al entorno de Produccin,
donde el cdigo se modifica niamente durante la subida nocturna y no afecta a los
usuarios en su trabajo normal.
7) Borrado ndices de funcin (FBI)

Los ndices de funcin (FBI) pueden ser borrados sin descompilar la paquetera que
usa la tabla a la que pertenece el ndice borrado.
8) Aadir columnas a tablas con valor por defecto

En la versin 10g, cuando se aade una columna con valor por defecto a una tabla
con miles de registros, Oracle debe bloquear la tabla (generando esperas al resto de
sesiones que quieran acceder a la tabla) y actualizar todos los registros al valor por
defecto, lo que origina gran cantidad de undo & redo, y tiempo para completar la
tarea:
10g.explotacion>
create table prueba as select level c1,
'valor_' || level || ' del total de registros' c2
2
from dual connect by level < 1000000;
Tabla creada.
10g.explotacion>

create unique index prueba_idx on prueba(c1);


ndice creado.
10g.explotacion>
begin
2
dbms_stats.gather_table_stats(ownname
3
tabname
4
method_opt
5
cascade
6
no_invalidate
7 end;
8 /

=>
=>
=>
=>
=>

'EXPLOTACION',
'PRUEBA',
'for all columns size REPEAT',
true,
false);

Procedimiento PL/SQL terminado correctamente.


10g.explotacion>
set timing on
10g.explotacion>
alter table prueba add
2
new_code varchar2(25) default '### default value ###' not null;
Tabla modificada.
Transcurrido: 00:01:56.05
10g.explotacion>
select * from prueba where c1 = 1;
C1 C2
NEW_CODE
---------- --------------------------------------- ------------------------1 valor_1 del total de registros
### default value ###
1 fila seleccionada.
Transcurrido: 00:00:00.04
10g.explotacion>
select * from table(dbms_xplan.display_cursor(NULL,null,'ALLSTATS LAST +COST'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------SQL_ID gd7nxmc6u6xg4, child number 0
------------------------------------select * from prueba where c1 = 1
Plan hash value: 2057855678
--------------------------------------------------------------------------------------------| Id | Operation
| Name
| Cost (%CPU)| A-Rows |
A-Time | Buffers |
--------------------------------------------------------------------------------------------|
1 | TABLE ACCESS BY INDEX ROWID| PRUEBA
|
3
(0)|
1 |00:00:00.01|
5 |
|* 2 | INDEX UNIQUE SCAN
| PRUEBA_IDX |
2
(0)|
1 |00:00:00.01|
3 |
---------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):


--------------------------------------------------2 - access("C1"=1)

En Oracle 11gR2, crear un nuevo campo con un valor por defecto no supone una
carga para la DB, puesto que en lugar de actualizar la tabla insertando el valor por
defecto en cada registro, si no que actualiza el valor por defecto como metadata, esto
supone un tiempo mnimo de actualizacin y cero generacin de undo o redo:
11gR2.explotacion>
create table prueba as select level c1,
2
'valor_' || level || ' del total de registros' c2
3
from dual connect by level < 1000000;
Tabla creada.
11gR2.explotacion>
create unique index prueba_idx on prueba(c1);
ndice creado.
11gR2.explotacion>

2
3
4
5
6
7
8

begin
dbms_stats.gather_table_stats(ownname
tabname
method_opt
cascade
no_invalidate
end;
/

=>
=>
=>
=>
=>

'EXPLOTACION',
'PRUEBA',
'for all columns size REPEAT',
true,
false);

Procedimiento PL/SQL terminado correctamente.


11gR2.explotacion>
set timing on
11gR2.explotacion>
alter table prueba add
2
new_code varchar2(25) default '### default value ###' not null;
Tabla modificada.
Transcurrido: 00:00:00.15
11gR2.explotacion>
select * from prueba where c1 = 1;
C1 C2
NEW_CODE
---------- ------------------------------------- ------------------------1 valor_1 del total de registros
### default value ###
1 fila seleccionada.
Transcurrido: 00:00:00.04
11gR2.explotacion>
select * from table(dbms_xplan.display_cursor(NULL,null,'ALLSTATS LAST +COST'));
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------SQL_ID gd7nxmc6u6xg4, child number 0
------------------------------------select * from prueba where c1 = 1
Plan hash value: 2057855678
---------------------------------------------------------------------------------------------| Id | Operation
| Name
| Cost (%CPU)| A-Rows |
A-Time | Buffers |
---------------------------------------------------------------------------------------------|
0 | SELECT STATEMENT
|
|
4 (100)|
1 |00:00:00.01|
4 |
|
1 | TABLE ACCESS BY INDEX ROWID| PRUEBA
|
4 (25)|
1 |00:00:00.01|
4 |
|* 2 |
INDEX UNIQUE SCAN
| PRUEBA_IDX |
2
(0)|
1 |00:00:00.01|
3 |
----------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):


--------------------------------------------------2 - access("C1"=1)

DESARROLLO
1) Hint IGNORE_ROW_ON_DUPKEY_INDEX

Este Hint est destinado a las sentencias insert into target select from source,
cuando del conjunto de filas seleccionado para ser insertado algunos registros podran
chocar con una restriccin de tipo unique en la tabla destino.
Hast ahora, si queramos realizar el insert descartando los registros duplicados tena
que hacerse registro a registro mediante cdigo PL/SQL controlando la excepcin
dup_val_on_index:
11gR2.explotacion>
drop table t_prueba purge;
Tabla borrada.
11gR2.explotacion>
create table t_prueba(

c1 number(5),
constraint pk_t_prueba primary key (c1) using index tablespace indx);
Tabla creada.
11gR2.explotacion>
insert into t_prueba values (5);
1 fila creada.
11gR2.explotacion>
commit;
Confirmacin terminada.
11gR2.explotacion> --> el insert directo falla
begin
2 insert into t_prueba select level from dual connect by level < 10;
3 commit;
4 end;
5 /
begin
*
ERROR en lnea 1:
ORA-00001: restriccin nica (EXPLOTACION.PK_T_PRUEBA) violada
ORA-06512: en lnea 2
11gR2.explotacion> --> hay que hacer insert registro a registro
begin
2
for reg in (select level as valor
3
from dual connect by level < 10) loop
4
begin
5
insert into t_prueba values (reg.valor);
6
exception
7
when DUP_VAL_ON_INDEX then
8
null;
9
end;
10
end loop;
11
commit;
12 end;
13 /
Procedimiento PL/SQL terminado correctamente.
11gR2.explotacion>
select * from t_prueba;
C1
---------1
2
3
4
5
6
7
8
9
9 filas seleccionadas.

En la versin Oracle 11g se aade el hint IGNORE_ROW_ON_DUPKEY_INDEX que


permite realizar el insert de los registros de forma directa, descartando aquellos que
no cumplen la restriccin unique:
11gR2.explotacion>
drop table t_prueba purge;
Tabla borrada.

11gR2.explotacion>
create table t_prueba(
c1 number(5),
constraint pk_t_prueba primary key (c1) using index tablespace indx);
Tabla creada.
11gR2.explotacion>
insert into t_prueba values (5);
1 fila creada.
11gR2.explotacion>
commit;
Confirmacin terminada.
11gR2.explotacion> --> insert directo con el nuevo hint
begin
2 insert /*+ IGNORE_ROW_ON_DUPKEY_INDEX (t pk_t_prueba)*/ into t_prueba t
3
select level from dual connect by level < 10;
4 commit;
5 end;
6 /
Procedimiento PL/SQL terminado correctamente.
11gR2.explotacion>
select * from t_prueba;
C1
---------1
2
3
4
5
6
7
8
9
9 filas seleccionadas.

Al poder realizarse la misma operacin con una sentencia SQL en lugar de todo un
bloque PL/SQL el rendimiento es mucho mayor.
2) Asignar valor de secuencias en expresiones PL/SQL

Ya no es necesario utilizar una select para asignar el valor de una secuencia a una
variable, se puede hacer directamente en la declaracion:
11GR2.explotacion>
create sequence seq start with 1;
Secuencia creada.
11GR2.explotacion>
declare
2 x number := seq.nextval;
3 begin
4 --> Ya no es necesario:
5 -- select seq.nextval into x from dual;
6 dbms_output.put_line(x);
7 end;
8 /
1
Procedimiento PL/SQL terminado correctamente.

Esta caracterstica mejora la usabilidad para el desarrollador de PL/SQL y aumenta la


escalabilidad y el rendimiento.

Вам также может понравиться