Antes de ir a la prueba me gustaría aclarar que si se ven tentados a usar este parámetro para acelerar el procesamiento, primero chequeen el diseño de transaccionabilidad de su aplicación y vean si es posible una vuelta de tuerca desde el lado del código, ya sea viendo si es posible "commitear" menos frecuentemente o si se esta "commiteando" en forma redundante, antes de ir una solución (quick and dirty) como es tocar el parámetro COMMIT_WRITE.
Para probar este parámetro, armé un bloque PL/SQL anónimo donde voy a probar las cuatro conbinaciones posibles del COMMIT_WRITE y voy a almacenar los resultados del test en la tabla RES para luego realizar una consulta que me permita comparar en forma sencilla cada opción.
SQL> create table T (X NUMBER(38),
2 Y VARCHAR2(10),
3 Z DATE)
/
Table created.
SQL>
SQL> create table RES (NAME VARCHAR2(200) not null,
2 VALUE NUMBER,
3 NCASE NUMBER(1) not null)
/
Table created.
rop@BPP3> begin
2 execute immediate 'truncate table res';
3
4 for i in 1..4 loop
5
6 case i when 1 then
7 execute immediate 'alter session set commit_write=''immediate,wait''';
8 when 2 then
9 execute immediate 'alter session set commit_write=''immediate,nowait''';
10 when 3 then
11 execute immediate 'alter session set commit_write=''batch,wait''';
12 when 4 then
13 execute immediate 'alter session set commit_write=''batch,nowait''';
14 end case;
15
16 insert into res
17 select 'STAT...' || a.name name,
18 b.value,
19 case i when 1 then 1
20 when 2 then 2
21 when 3 then 3
22 when 4 then 4
23 end
24 from v$statname a, v$mystat b
25 where a.statistic# = b.statistic#
26 union all
27 select 'LATCH.' || name,
28 gets,
29 case i when 1 then 1
30 when 2 then 2
31 when 3 then 3
32 when 4 then 4
33 end
34 from v$latch
35 union all
36 select 'STAT...Elapsed Time',
37 hsecs,
38 case i when 1 then 1
39 when 2 then 2
40 when 3 then 3
41 when 4 then 4
42 end
43 from v$timer;
44
45 for j in (select trunc(dbms_random.value(1,10000)) x,
46 dbms_random.string('a',10) y,
47 sysdate+dbms_random.value(-300,300) z
48 from dual
49 connect by rownum <= 100000)
50 loop
51 insert into t values (j.x,j.y,j.z);
52 commit;
53 end loop;
54
55 for k in (select 'STAT...' || a.name name, b.value
56 from v$statname a,
57 v$mystat b
58 where a.statistic# = b.statistic#
59 union all
60 select 'LATCH.' || name, gets
61 from v$latch
62 union all
63 select 'STAT...Elapsed Time',hsecs
64 from v$timer)
65 loop
66 update res
67 set value = (k.value-value)
68 where res.name = k.name
69 and res.ncase = i;
70 end loop;
71 commit;
72 end loop;
73 end;
/
PL/SQL procedure successfully completed.
Ahora voy a ejecutar una consulta sobre la tabla de resultados de forma tal de encolumnar cada caso y poder comparar mas facilmente.
rop@BPP3> select name,
max(decode(ncase,1,value,null)) "IMMEDIATE,WAIT",
max(decode(ncase,2,value,null)) "IMMEDIATE,NOWAIT",
max(decode(ncase,3,value,null)) "BATCH,WAIT",
max(decode(ncase,4,value,null)) "BATCH,NOWAIT"
from res
group by name
NAME IMMEDIATE,WAIT IMMEDIATE,NOWAIT BATCH,WAIT BATCH,NOWAIT
------------------------------------------------------------ -------------- ---------------- ---------- ------------
STAT...recursive cpu usage 1393 887 1293 849
STAT...messages sent 100040 10449 100008 53
STAT...commit wait requested 100000 0 100000 0
STAT...SMON posted for undo segment shrink 0 0 0 0
STAT...commit batch performed 0 0 100000 100000
STAT...commit immediate performed 100000 100000 0 0
STAT...commit nowait performed 0 100000 0 100000
LATCH.session timer 19 3 34 3
STAT...redo synch time 4042 0 8777 0
STAT...commit batch requested 0 0 100000 100000
STAT...commit wait/nowait requested 100000 100000 100000 100000
STAT...commit wait performed 100000 0 100000 0
LATCH.messages 287070 23614 462948 447
STAT...Elapsed Time 5543 965 10056 927
STAT...redo synch writes 100000 0 100000 0
STAT...commit batch/immediate requested 100000 100000 100000 100000
STAT...commit immediate requested 100000 100000 0 0
LATCH.Consistent RBA 100035 10447 100015 54
LATCH.cache buffers lru chain 652 600 4870 3282
LATCH.object queue header heap 93 16 216728 344
LATCH.redo allocation 587541 414896 504629 304247
LATCH.JS queue state obj latch 396 72 720 72
STAT...CPU used by this session 1493 956 1388 915
STAT...session pga memory max 4587520 65536 0 0
STAT...commit nowait requested 0 100000 0 100000
LATCH.client/application info 4 0 8 0
LATCH.OS process allocation 19 3 34 3
LATCH.active checkpoint queue latch 24 5 54186 89
LATCH.archive process latch 26 9 46 9
LATCH.post/wait queue 150161 5 150132 3
LATCH.parameter table allocation management 2 0 4 0
LATCH.redo writing 300168 31357 354299 258
El resultado de la consulta me arrojó mas de 700 estadisticas y latches. Solo copié
las filas donde noté diferencias importantes en los casos. En especial, la fila resaltada (Elapsed Time) muestra el tiempo total de procesamiento en cada caso en centisegundos. Como se observa para los casos donde se usa WAIT los tiempos son bastante mayores, lo cual comprueba la mejora en performance al usar asincronismo (NOWAIT).
Mientras escribia esta nota descubrí que en 11g el parametro commit_write esta "deprecated", parece que tuvo poca vida, no?. De todas formas la documentación aclara que fue reemplazado por los parametros COMMIT_WAIT y COMMIT_LOGGING.
Usando estos dos nuevos parametros en conjunto se obtendría el mismo funcionamiento que COMMIT_WRITE, aunque que el parametro COMMIT_WAIT agregó una nueva opción para forzar el wait (force_wait)
Pablo, muy bueno el articulo y me fue de mucha utlidad a la hora de generar un reporte profesional.
ResponderEliminarSaludos,
Juan Andrés,
Me alegro que te haya servido la info. Slds
ResponderEliminar