Tuning SQL : Lo malo de usar UNION en los select :)



Hace poco acabo de terminar un curso de Tuning de SQL ,el código es el D19165GC20 , en ese curso hay muchos detalles los cuales uno maneja a diario, pero de lo cual en mi caso nunca he escrito.

He aquí un ejemplo, el porque siempre se debiese ocupar el UNION ALL , en vez del UNION , esto último debido a que el UNION provoca un ordenamiento implicito de los datos dentro de la PGA , a pesar de que como todos sabemos el UNION ALL entrega todas las filas a pesar de que estas se repitan , el UNION sólo entrega aquellas diferentes.

He aquí el caso del porque es tan caro el simple, común y pequeño UNION ;)

Para realizar los ejemplos, hemos creado 7 tablas las cuales tienen informacion desde la dba_objects, o sea, cada una de estas tablas posee como 55 mil registros, mas o menos.

Vaciamos la memoria, de todo bloque para que la prueba sea más acertiva.

alter system flush shared_pool ;
alter system flush buffer_cache ;

Primero utilizamos el simple UNION

select * from tabla_full_1
union
select * from tabla_full_2
union
select * from tabla_full_3
union
select * from tabla_full_4
union
select * from tabla_full_5
union
select * from tabla_full_6
union
select * from tabla_full_7
;

Cantidad de filas traídas en la consulta

50610 rows selected.

Y observamos el plan de ejecución

Execution Plan
----------------------------------------------------------
Plan hash value: 3784107405

--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 708K| 28M| | 8800 (86)| 00:01:46 |
| 1 | SORT UNIQUE | | 708K| 28M| 76M| 8800 (86)| 00:01:46 |
| 2 | UNION-ALL | | | | | | |
| 3 | TABLE ACCESS FULL| TABLA_FULL_1 | 101K| 4151K| | 151 (3)| 00:00:02 |
| 4 | TABLE ACCESS FULL| TABLA_FULL_2 | 101K| 4151K| | 152 (3)| 00:00:02 |
| 5 | TABLE ACCESS FULL| TABLA_FULL_3 | 101K| 4151K| | 152 (3)| 00:00:02 |
| 6 | TABLE ACCESS FULL| TABLA_FULL_4 | 101K| 4151K| | 152 (3)| 00:00:02 |
| 7 | TABLE ACCESS FULL| TABLA_FULL_5 | 101K| 4151K| | 152 (3)| 00:00:02 |
| 8 | TABLE ACCESS FULL| TABLA_FULL_6 | 101K| 4151K| | 152 (3)| 00:00:02 |
| 9 | TABLE ACCESS FULL| TABLA_FULL_7 | 101K| 4151K| | 152 (3)| 00:00:02 |
--------------------------------------------------------------------------------------------

Como lo aprecian , esta ordenando 28MB de información lo cual consume 76MB de espacio temporal (o sea , se esta utilizando disco) , lo cual produce I/O muy costoso.

Statistics
----------------------------------------------------------
1423 recursive calls
0 db block gets
4876 consistent gets
4679 physical reads
0 redo size
2262291 bytes sent via SQL*Net to client
37503 bytes received via SQL*Net from client
3375 SQL*Net roundtrips to/from client
22 sorts (memory)
0 sorts (disk)
50610 rows processed

Nuevamente borramos todo vestigio desde memoria.

alter system flush shared_pool ;
alter system flush buffer_cache ;

Y ejecutamos la misma consulta, pero esta vez con UNION ALL

select * from tabla_full_1
union all
select * from tabla_full_2
union all
select * from tabla_full_3
union all
select * from tabla_full_4
union all
select * from tabla_full_5
union all
select * from tabla_full_6
union all
select * from tabla_full_7
;

Trae efectivamente mas de 700 mil registros, los cuales debiesen ser procesados con un cursor, para así descartar los repetidos, es más barato y más rápido

708540 rows selected.

El plan de ejecución de la sentencia con UNION ALL

Execution Plan
----------------------------------------------------------
Plan hash value: 2473866688

-----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 708K| 28M| 1061 (87)| 00:00:13 |
| 1 | UNION-ALL | | | | | |
| 2 | TABLE ACCESS FULL| TABLA_FULL_1 | 101K| 4151K| 151 (3)| 00:00:02 |
| 3 | TABLE ACCESS FULL| TABLA_FULL_2 | 101K| 4151K| 152 (3)| 00:00:02 |
| 4 | TABLE ACCESS FULL| TABLA_FULL_3 | 101K| 4151K| 152 (3)| 00:00:02 |
| 5 | TABLE ACCESS FULL| TABLA_FULL_4 | 101K| 4151K| 152 (3)| 00:00:02 |
| 6 | TABLE ACCESS FULL| TABLA_FULL_5 | 101K| 4151K| 152 (3)| 00:00:02 |
| 7 | TABLE ACCESS FULL| TABLA_FULL_6 | 101K| 4151K| 152 (3)| 00:00:02 |
| 8 | TABLE ACCESS FULL| TABLA_FULL_7 | 101K| 4151K| 152 (3)| 00:00:02 |
-----------------------------------------------------------------------------------

Y como se puede apreciar, no hay uso de espacio temporal , sólo se procesan los 28MB de datos.

Statistics
----------------------------------------------------------
1423 recursive calls
0 db block gets
51700 consistent gets
4679 physical reads
0 redo size
27134781 bytes sent via SQL*Net to client
519985 bytes received via SQL*Net from client
47237 SQL*Net roundtrips to/from client
21 sorts (memory)
0 sorts (disk)
708540 rows processed

Para que se tenga en cuenta al momento de realizar un programa

Espero les sirva

by Ligarius
17.08.09. 09:28:17. 626 words, 8654 views. Categories: Oracle 10g, Tuning / Performance ,

Calculando el tamaño actual de la Shared Pool



Me hicieron una consulta con respecto al tamaño actual de la Shared Pool cuando Oracle trabaja con ASMM (Automatic Shared Memory Management) o manejo automático de memoria.

Y el primer pensamiento fue casi instintivo

"Dentro de la gv$parameter2"



mm , pero dando una vuelta al tema, en esa vista aparece la Shared Pool Size en 0 , ¿el porqué? , pues con ASMM 5 buffers de memoria son trabajados de forma automática


DB_CACHE_SIZE
JAVA_POOL_SIZE
STREAMS_POOL_SIZE
LARGE_POOL_SIZE
SHARED_POOL_SIZE


Siempre los mostrará en 0 , ya que internamente el maneja un tamaño en esos buffers total y absolutamente dinámico

La pregunta calza de inmediato ¿Cómo veo el valor actual de la Shared Pool ?, no importanto si tengo o no ASMM |-|

Y añadiendo mas complejidad

¿Cómo obtengo el tamaño de la Shared Pool en una ambiente con ASMM y sin ASMM en versiones Oracle9i, Oracle10g y Oracle11g? CON EL MISMO SCRIPT??? :crazy:

Pues aca esta el ensayo de esa pequeña problemática

SI sga_target > 0 ENTONCES

Valor actual dentro de la SGA

select name ,
bytes/1024/1024 MB
from v$sgainfo
where upper(name) like '%SHARED POOL SIZE%'

Válido para : Oracle10g , Oracle11g
No válido para : Oracle9i

o

Valor actual del parámetro , como resize del MMAN y MMON

select component ,
current_size/1024/1024 MB
from v$sga_dynamic_components
where component like '%shared pool%'


Válido para : Oracle9i , Oracle10g , Oracle11g

0

Esta forma de consultar la shared pool , es la mas interna ya que no pasamos por ninguna vista del diccionario de datos

select b.ksppinm "Parametro re-oculto",
a.KSPFTCTXVL "Bytes",
a.KSPFTCTXDVL "Mb"
from X$KSPPCV2 a ,
x$ksppi b
where b.indx + 1 = a.kspftctxpn
and b.KSPPINM like '__shared_pool_size'

Válido para : Oracle10g , Oracle11g
No válido para : Oracle9i

o

Ejecutando el comando CREATE PFILE FROM SPFILE
Y dentro del init creado , buscar el parámetro __shared_pool_size

SQL> CREATE PFILE FROM SPFILE;

Válido para : Oracle10g , Oracle11g
No válido para : Oracle9i


SINO SI sga_target = 0 ENTONCES (con y sin bajada de instancia)

Valor actual dentro de la SGA

select name ,
bytes/1024/1024 MB
from v$sgainfo
where upper(name) like '%SHARED POOL SIZE%'

Válido para : Oracle10g , Oracle11g
No válido para : Oracle9i


o

Valor actual del parámetro , como resize del MMAN y MMON

select component ,
current_size/1024/1024 MB
from v$sga_dynamic_components
where component like '%shared pool%'

Válido para : Oracle9i , Oracle10g , Oracle11g

0

Esta forma de consultar la shared pool , es la mas interna ya que no pasamos por ninguna vista del diccionario de datos

select b.ksppinm "Parametro re-oculto",
a.KSPFTCTXVL "Bytes",
a.KSPFTCTXDVL "Mb"
from X$KSPPCV2 a ,
x$ksppi b
where b.indx + 1 = a.kspftctxpn
and b.KSPPINM like '__shared_pool_size'


Válido para : Oracle10g , Oracle11g
No válido para : Oracle9i


o

Mediante el parámetro seteado en el archivo de inicialización

SELECT value/1024/1024||' [MB]' alias_shared_pool_size
FROM gv$parameter2
WHERE name = 'shared_pool_size'
AND value <> '0'


Válido para : Oracle9i , Oracle10g , Oracle11g

FIN SI.

Saquen ustedes sus propias conclusiones para obtener ese maldito valor :>>

by Ligarius
07.08.09. 16:23:44. 562 words, 8627 views. Categories: Tuning / Performance ,

Una gran enseñanza de vida , para que no nos quejemos tanto ...



Acabo de finalizar el curso de Performance Tuning de Oracle 10g (cod D19165GC11) , fue un full day de 4 días

En el conocí a Patricio Yufla, hablamos poco , casi al finalizar el curso .

Y de verdad quede muy impresionado con su historia de vida.




El nacio con la enfermedad de Charcot-Marie-Tooth.

Esa enfermedad se le presento cuando tenía 3 años y medio y es degenerativa, lo que hizo que al salir de la enseñanza secundaria dejará de caminar, de hecho lo intentaba pero se le doblaban las rodillas.

Y de a poco comenzo a perder la movilidad de sus dedos y finalmente quedo en silla de ruedas.

El vive en Calama a 1.225kms de Santiago y allá decidio con todo y enfermedad ponerse a estudiar, obtuvo la Ingeniería Informática en el Inacap y después obtuvo un diplomado en la Universidad Católica del Norte de Chile.

La verdad es tremendamente meritorio andar en una silla de ruedas por Santiago y subirse al Metro que vive colapsado.

De hecho Patricio ya ha realizado 3 cursos en In Motion, y les puedo comentar que le coloca mucho empeño en clases , y escucha muy atentamente, a pesar de que ya por ejemplo perdio la capacidad de realizar pinzas con sus manos, pero trata de escribir, trata de teclear en el computador y por supuesto tiene intención de trabajar.

Imaginense lo que significa todo eso si al le dijeron que a los 30 años iba a estar casi vegetal, y el anda paseando en avión , yendo a curso y paseando por Santigo

Te felicito PATRICIO!!!

by Ligarius
04.08.09. 08:30:29. 269 words, 5074 views. Categories: Cosas varias ,

Está es la vida del informático



De verdad que no pude aguantar pero realmente en el mundo informático , esto se da seguido

Realmente simpático :>> y bastante cierto



¿A quién no le ha pasado que venden un tanque para matar una mosca? :yes:

by Ligarius
29.07.09. 20:19:02. 39 words, 5072 views. Categories: Cosas varias , 1 comment »Send a trackback »

Por fin la matriz que necesitaba , todo linux en Oracle



Siempre buscamos esa guía divina , esa nota condensada donde salgan los "tips" , resumenes, how to , prácticos y concisos.. cierto?



Pero... siempre nos encontramos con 20.657 páginas para leer y 12.453 notas , y eso la verdad cansa :(

En pro de solucionar eso, Oracle lanzo una notita en donde resume de una gran forma , todos los prerequisitos de Oracle en plataformas Linux, y de verdad ES LA NOTA QUE BUSCABA!!!

La nota Oracle es la siguiente

Note 851598.1 : Linux OS Requirements Reference List for Database Server

Y dentro de ella, podemos encontrar todo lo que necesitamos

Red Hat Enterprise Linux (RHEL)
RHEL5: x86 x86_64 Itanium zLinux Power
RHEL4: x86 x86_64 Itanium zLinux Power
RHEL3: x86 x86_64 Itanium zLinux Power

SuSE Linux Enterprise Server (SLES)
x86 x86_64
SLES10: x86 x86_64 zLinux
SLES 9: x86 x86_64 zLinux

Oracle Enterprise Linux (OEL)
OEL5: x86 x86_64
OEL4: x86 x86_64

Además nos proporciona como nota una Quick Reference

Note 169706.1 Installation and Configuration Requirements Quick Reference

Espero les sirva

by Ligarius
23.07.09. 07:59:34. 161 words, 4213 views. Categories: Base de datos, Instalación ,

<< 1 ... 33 34 35 36 37 38 39 40 41 42 43 ... 44 >>