UnDomain Un friki suelto por la red

Preview de tunning en una BDD


Uno de los principales puntos clave en una BDD es el rendimiento, y también es una de las cosas más complicadas.
Muchas veces, los problemas de rendimiento son "culpa" de los programas (aquí incluyo el modelo de datos). Otras veces es cosa de la configuración de la propia BDD, que no se ajusta a los requerimientos de la aplicación o a su evolución.

La siguiente "query" nos sirve para saber el estado general de una BDD, de manera que nos hace una especie de "preview" para poder oriental las acciones de tunning de la BDD. Nos indica algunos de los parámetros clave a modificar (generalmente ampliar) dependiendo de los resultados.

Aquí tenemos la susodicha, ojo que es larga :

SELECT 'Instancia y Host' "DESCRIPCION", INSTANCE_NAME||' ('||HOST_NAME||')' "VALOR", NULL "COMENTARIO" FROM V$INSTANCE
UNION ALL
SELECT NAME, TO_CHAR(TO_NUMBER(VALUE)/1024/1024)||' MB', NULL FROM V$PARAMETER WHERE NAME ='shared_pool_size'
UNION ALL
SELECT NAME, TO_CHAR(ROUND(BYTES/1024/1024,2))||' MB', NULL FROM V$SGASTAT WHERE POOL = 'shared pool' AND NAME = 'free memory'
UNION ALL
SELECT 'Miss Ratio', TO_CHAR(ROUND(SUM(GETMISSES)/SUM(GETS),2))||'%' "MISS RATIO", DECODE(SIGN(ROUND(SUM(GETMISSES)/SUM(GETS),0)-15), -1,NULL,'Ampliar SHARED_POOL_SIZE') FROM V$ROWCACHE
UNION ALL
SELECT 'Reparsed querys', TO_CHAR(COUNT(*)), DECODE(SIGN(COUNT(*)-1),-1,NULL,'Ampliar SHARED_POOL_SIZE') FROM V$SQLAREA A, V$SQLTEXT T WHERE PARSE_CALLS >1 AND PARSE_CALLS = EXECUTIONS AND A.ADDRESS=T.ADDRESS AND EXECUTIONS > 10000
UNION ALL
SELECT 'Hit Ratio', TO_CHAR(ROUND(SUM(PINHITS) / SUM(PINS) * 100 ,2))||'%', DECODE(SIGN(ROUND(SUM(PINHITS) / SUM(PINS) * 100 ,0)-85),-1,'Ampliar SHARED_POOL_SIZE y/o el OPEN_CURSORS',NULL) FROM V$LIBRARYCACHE WHERE NAMESPACE IN ('SQL AREA', 'TABLE/PROCEDURE', 'BODY', 'TRIGGER')
UNION ALL
SELECT 'Reload percent', TO_CHAR(ROUND(SUM(RELOADS) / SUM(PINS) * 100 ,2))||'%', DECODE(SIGN(ROUND(SUM(RELOADS) / SUM(PINS) * 100 ,0)-2),-1,NULL,'Ampliar SHARED_POOL_SIZE y/o el OPEN_CURSORS') FROM V$LIBRARYCACHE WHERE NAMESPACE IN ('SQL AREA', 'TABLE/PROCEDURE', 'BODY', 'TRIGGER')
UNION ALL
SELECT 'Cache Hit Ratio', TO_CHAR(ROUND(100*(1 - (V3.VALUE / (V1.VALUE + V2.VALUE))),2))||'%', DECODE(SIGN(ROUND(100*(1 - (V3.VALUE / (V1.VALUE + V2.VALUE))),0)-85),-1,'Ampliar DB_CACHE_SIZE',NULL) FROM V$SYSSTAT V1, V$SYSSTAT V2, V$SYSSTAT V3 WHERE V1.NAME = 'db block gets' AND V2.NAME = 'consistent gets' AND V3.NAME = 'physical reads'
UNION ALL
SELECT NAME, TO_CHAR(VALUE), DECODE(NAME,'sorts (disk)',decode(sign((value*100/(select sum(value) from V$SYSSTAT WHERE NAME IN ('sorts (memory)', 'sorts (disk)')))-25),-1,NULL,'Ampliar la SORT_AREA_SIZE'),NULL) FROM V$SYSSTAT WHERE NAME IN ('sorts (memory)', 'sorts (disk)')
UNION ALL
SELECT NAME, TO_CHAR(VALUE), DECODE(NAME,'redo log space wait time',DECODE(SIGN(VALUE-1),-1,NULL,'Ampliar el LOG_BUFFER'),NULL) FROM V$SYSSTAT WHERE NAME IN('redo log space requests', 'redo log space wait time')
UNION ALL
SELECT 'Esperas de segmentos de Rollback' , TO_CHAR(ROUND(SUM(WAITS)/SUM(GETS)*100,2))||'%', DECODE(SIGN(ROUND(SUM(WAITS)/SUM(GETS)*100,0)-1),-1,NULL,'Crear mas segmentos de rollback') FROM V$ROLLSTAT
UNION ALL
SELECT 'Tablas fragmentadas (>100 Extents) -> '||OWNER , TO_CHAR(COUNT(*)), DECODE(SIGN(COUNT(*)-1),-1,NULL,'Realizar tareas de desfragmentacion sobre la tablas. Para identificarlas: "SELECT OWNER, SEGMENT_NAME TABLE_NAME, TABLESPACE_NAME, EXTENTS FROM DBA_SEGMENTS WHERE SEGMENT_TYPE=''TABLE'' AND OWNER='''||OWNER||''' AND EXTENTS>25 ORDER BY EXTENTS DESC;"') FROM DBA_SEGMENTS WHERE SEGMENT_TYPE='TABLE' AND OWNER NOT IN ('SYS', 'SYSTEM', 'OLAPSYS', 'WKSYS', 'CTXSYS', 'RMAN', 'ODM', 'WMSYS', 'MDSYS', 'QS', 'QS_ES', 'QS_OS', 'QS_WS', 'ODM_MTR', 'QS_CBADM', 'QS_CS', 'ORDSYS', 'XDB', 'SCOTT', 'OUTLN', 'OE') AND EXTENTS>100 GROUP BY OWNER
UNION ALL
SELECT 'Indices fragmentados (>100 Extents) -> '||OWNER, TO_CHAR(COUNT(*)), DECODE(SIGN(COUNT(*)-1),-1,NULL,'Recrear los indices fragmentados. Para identificarlos: "SELECT A.OWNER, B.TABLE_NAME, A.SEGMENT_NAME INDICE, A.TABLESPACE_NAME, A.EXTENTS FROM DBA_SEGMENTS A, ALL_INDEXES B WHERE A.SEGMENT_TYPE=''INDEX'' AND B.OWNER=A.OWNER AND B.INDEX_NAME=A.SEGMENT_NAME AND EXTENTS>25 AND A.OWNER='''||OWNER||''' ORDER BY EXTENTS DESC;"') FROM DBA_SEGMENTS WHERE SEGMENT_TYPE='INDEX' AND OWNER NOT IN ('SYS', 'SYSTEM', 'OLAPSYS', 'WKSYS', 'CTXSYS', 'RMAN', 'ODM', 'WMSYS', 'MDSYS', 'QS', 'QS_ES', 'QS_OS', 'QS_WS', 'ODM_MTR', 'QS_CBADM', 'QS_CS', 'ORDSYS', 'XDB', 'SCOTT', 'OUTLN', 'OE') AND EXTENTS>100 GROUP BY OWNER
UNION ALL
SELECT 'Tablas con estadisticas antiguas -> '||OWNER, TO_CHAR(COUNT(*)), DECODE(COUNT(*),0,NULL,'Actualiza las estadisticas con "SELECT ''ANALYZE TABLE ''||OWNER||''.''||TABLE_NAME||'' COMPUTE STATISTICS;'' FROM DBA_TABLES WHERE OWNER='''||OWNER||''' AND LAST_ANALYZED UNION ALL
SELECT 'Tablas sin estadisticas -> '||OWNER, TO_CHAR(COUNT(*)),DECODE(COUNT(*),0,NULL,'Actualiza las estadisticas con "SELECT ''ANALYZE TABLE ''||OWNER||''.''||TABLE_NAME||'' COMPUTE STATISTICS;'' FROM DBA_TABLES WHERE OWNER='''||OWNER||''' AND LAST_ANALYZED IS NULL;"') FROM DBA_TABLES WHERE OWNER NOT IN ('SYS', 'SYSTEM', 'OLAPSYS', 'WKSYS', 'CTXSYS', 'RMAN', 'ODM', 'WMSYS', 'MDSYS', 'QS', 'QS_ES', 'QS_OS', 'QS_WS', 'ODM_MTR', 'QS_CBADM', 'QS_CS', 'ORDSYS', 'XDB', 'SCOTT', 'OUTLN', 'OE') AND LAST_ANALYZED IS NULL GROUP BY OWNER
UNION ALL
SELECT 'Indices con estadisticas antiguas -> '||OWNER, TO_CHAR(COUNT(*)), DECODE(COUNT(*),0,NULL,'Actualiza las estadisticas con "SELECT ''ANALYZE INDEX ''||OWNER||''.''||INDEX_NAME||'' COMPUTE STATISTICS;'' FROM DBA_INDEXES WHERE OWNER='''||OWNER||''' AND LAST_ANALYZED UNION ALL
SELECT 'Indices sin estadisticas -> '||OWNER, TO_CHAR(COUNT(*)),DECODE(COUNT(*),0,NULL,'Actualiza las estadisticas con "SELECT ''ANALYZE INDEX ''||OWNER||''.''||INDEX_NAME||'' COMPUTE STATISTICS;'' FROM DBA_INDEXES WHERE OWNER='''||OWNER||''' AND LAST_ANALYZED IS NULL;"') FROM DBA_INDEXES WHERE OWNER NOT IN ('SYS', 'SYSTEM', 'OLAPSYS', 'WKSYS', 'CTXSYS', 'RMAN', 'ODM', 'WMSYS', 'MDSYS', 'QS', 'QS_ES', 'QS_OS', 'QS_WS', 'ODM_MTR', 'QS_CBADM', 'QS_CS', 'ORDSYS', 'XDB', 'SCOTT', 'OUTLN', 'OE') AND LAST_ANALYZED IS NULL GROUP BY OWNER;
El resultado de esta query viene a ser una especie de mini-informe con algunos consejos. P.E.:

DESCRIPCION VALOR COMENTARIO
Instancia y Host chicago (TESTORACLE1)  
shared_pool_size 0 MB  
free memory 16,69 MB  
Miss Ratio ,02%  
Reparsed querys 20 Ampliar SHARED_POOL_SIZE
Hit Ratio 98,75%  
Reload percent ,24%  
Cache Hit Ratio 99,75%  
sorts (memory) 729381  
sorts (disk) 0  
redo log space requests 49  
redo log space wait time 690 Ampliar el LOG_BUFFER
Esperas de segmentos de Rollback 0%  
Tablas con estadisticas antiguas -> TSMSYS 1 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='TSMSYS' AND LAST_ANALYZED<SYSDATE-7;"
Tablas con estadisticas antiguas -> DMSYS 2 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='DMSYS' AND LAST_ANALYZED<SYSDATE-7;"
Tablas con estadisticas antiguas -> MOI 1 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='MOI' AND LAST_ANALYZED<SYSDATE-7;"
Tablas con estadisticas antiguas -> EXFSYS 42 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='EXFSYS' AND LAST_ANALYZED<SYSDATE-7;"
Tablas con estadisticas antiguas -> DBSNMP 18 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='DBSNMP' AND LAST_ANALYZED<SYSDATE-7;"
Tablas con estadisticas antiguas -> SYSMAN 283 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='SYSMAN' AND LAST_ANALYZED<SYSDATE-7;"
Tablas sin estadisticas -> EXFSYS 2 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='EXFSYS' AND LAST_ANALYZED IS NULL;"
Tablas sin estadisticas -> SYSMAN 1 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='SYSMAN' AND LAST_ANALYZED IS NULL;"
Tablas sin estadisticas -> DBSNMP 3 Actualiza las estadisticas con "SELECT 'ANALYZE TABLE '||OWNER||'.'||TABLE_NAME||' COMPUTE STATISTICS;' FROM DBA_TABLES WHERE OWNER='DBSNMP' AND LAST_ANALYZED IS NULL;"
Indices con estadisticas antiguas -> TSMSYS 1 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='TSMSYS' AND LAST_ANALYZED<SYSDATE-7;"
Indices con estadisticas antiguas -> DMSYS 2 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='DMSYS' AND LAST_ANALYZED<SYSDATE-7;"
Indices con estadisticas antiguas -> EXFSYS 36 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='EXFSYS' AND LAST_ANALYZED<SYSDATE-7;"
Indices con estadisticas antiguas -> DBSNMP 8 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='DBSNMP' AND LAST_ANALYZED<SYSDATE-7;"
Indices con estadisticas antiguas -> SYSMAN 308 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='SYSMAN' AND LAST_ANALYZED<SYSDATE-7;"
Indices sin estadisticas -> TSMSYS 1 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='TSMSYS' AND LAST_ANALYZED IS NULL;"
Indices sin estadisticas -> EXFSYS 3 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='EXFSYS' AND LAST_ANALYZED IS NULL;"
Indices sin estadisticas -> SYSMAN 29 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='SYSMAN' AND LAST_ANALYZED IS NULL;"
Indices sin estadisticas -> DBSNMP 2 Actualiza las estadisticas con "SELECT 'ANALYZE INDEX '||OWNER||'.'||INDEX_NAME||' COMPUTE STATISTICS;' FROM DBA_INDEXES WHERE OWNER='DBSNMP' AND LAST_ANALYZED IS NULL;"


Esta "pequeña" query la he montado a base de consultas utilizadas para tunning de BDD y se calcula con valores genéricos, por lo que puede no ser exacto, pero útil para controlar el estado de optimización de varias BDD o para sacar un informe de estado general.

En cuanto a las ampliaciones de los valores indicados, no existe una cantidad o porcentaje determinado. Oracle recomienda hacer pequeñas ampliaciones (entorno al 5%), pero todo depende de los valores que ya tengas y de los recursos que dispongas.

Pues ala.... ya podéis ver como tenéis la BDD :)

Te has quedado a gusto con la

Te has quedado a gusto con la consulta no? xDDDD
Yo comentaría dos cosas, la primera es que en lugar de consultas de estado, deberías usar el statspack (cada 15-20 min) en 8i-9i y a partir de 10g el AWR (el hermano guapo del statspack ;))
Y sobre las consultas sin estadisticas, varios apuntes:
- Elimina los schemas que no sean propios de la aplicacion, DBSMP, SYSMAN y demás no deberias tocarlos de forma generica, y menos ese esquema MOI, suena peligroso XD
- No uses ANALYZE para analizar las tablas e indices, utiliza DBMS_STATS, mucho mas potente y eficaz.
- Hay tablas de aplicacion que es mejor NO analizar, en serio xD
- Analizar semanalmente es un poco bestia (filtras tablas e indices con analisis anteriores a 7 dias), con el propio dbms_stats puedes hacer que te indique cuales son aquellos objetos que necesitan reanalisis.

Ala ya ta, no quiero hacerme pesado :)

La verdad es que la parte de

La verdad es que la parte de las estadisticas es más a modo informativo, aunque realmene el DBMS_STATS hace un analyze guardando las estadisticas previas en un historico (en el tablespace SYSAUX) para poder hacer una estauracion de estadisticas (la verdad es que no se para que se puede utilizar).
La idea de esta query es tener un punto de partida...ademas se puede utilziar en BDD 8i p'arriba y creo que el paquete de STATS está en la 10g (creo que tambien está en la 9i, pero Oracle no recomendaba su uso, algo le pasaria).

En realidad, lo mas importante del resultado de la query son las primeras lineas y está pensado mas para sacar informes rapidos sin tener que tirar e los statspacs (eso es para entrar mas a saco en el rendimiento de una BDD,y esta query es para tener una primera impresión orientativa, esto no es la panacea)...cuando tienes que monitorizar muchas BDD, esto se agradece :)

Lo siento pero no puedo estar

Lo siento pero no puedo estar de acuerdo...
Statspack (y AWR mucho mas) te saca estadísticas que luego consultas para ver el estado real de la bbdd, es un procedimiento que guarda en tablas y puedes hacer consultas comparativas mucho más exactas y que te dan una idea en el tiempo mucho mas acertada.
Y sobre dbms_stats, nunca he visto una nota de Oracle recomendando no utilizarlo, es más, todo lo contrario, consideran analyze un tanto deprecado, al igual que el DBMS_UTILITY.ANALYZE_SCHEMA.
Entre las ventajas del dbms_stats sobre analyze (con las que podria estar un buen rato xD), el lanzar estadisticas en paralelo (vital para no eternizar procesos de estadisticas en bases de datos medias-grandes), analizar un schema completo con una sola sentencia, tener un registro de las tablas e indices que realmente necesitan ser analizadas, el metodo COMPUTE, etc
Analyze yo solo lo usaria para pruebas rapidas de optimizacion de querys concretas, y nunca en produccion...

saludetes!

Creo que no me has

Creo que no me has entendido...

Para que los statpacs tengan datos que se puedan analizar necesitas activarlos y esperar un tiempo prudencial con una carga de trabajo real para conseguir datos suficientes (yo opino que menos de una semana es insuficiente, pero es mi opinión).

Con esta query (ignora el script de analyze si quieres, eso solo es una "ayuda") consigues unos datos desde los que partir y se puede tomar como una pequeña avanzada a los resultados de los statpacs.

En cuanto al DBMS_STATS, si no estoy mal informado, es nuevo de la 10g. Por lo tanto, los scripts de analyze son útiles para BDD 9i e inferiores (puede que incluso funcione en una 7), ya que estas utilidades estan "deprecadas" ahora, pero no cuando salieron esas versiones.

Vamos, que esto es mas para tomar una "primera impresion". Por descontado lo mejor es hacer un analisis exaustivo con los STATPACS, pero esto requiere mas tiempo y te puede interesar tomar unas medidas immediatas para "apaciguar algunas mentes pensantes" y que no den el coñazo (tu ya me entiendes ;)).

mmmm, no es exactamente lo

mmmm, no es exactamente lo que quería decirte...
Antes de nada, el statspack es recomendable tenerlo siempre, con una ejecucion de no mas de 15-20 min entre fotos... de hecho el AWR de la 10g está siempre monitorizando :). Para 8i hay una cosa llamada BSTATS o algo asi (el padre del statspack)
Y lo que te queria decir, el statspack no solo sirve para generar informes, sino que almacena informacion en su esquema que puedes consultar sin tener que machacar las fixed tables, y con una exactitud buena (de 15-20 o menos, segun configures). No te digo que te pongas a liarte con los informes del "amigo" (que si lo pones a mas de 7 de "profundidad", no te los acabas), sino que, en mi opinion, es mejor montar querys que ataquen a esas tablas ya que te permite incluso hacer comparativas (y te hablo de una query de primera impresion eh)

Sobre el dbms_stats, en la 9i ya lo tienes y lo debes usar. La primera version salio para la 8.1.5 (usea, 8, asi que en 8i (8.1.7) debia ser estable ya pero yo lo descubri para la 9).
Creo que en la 7 lo que estaba de moda era el dbms_utility porque el analyze para indices funcionaba como el culo (sino preguntale al staffware xDDDDDDDD)

(1+1 =2 XD)

Ahora tu CAPTCHA ya me

Ahora tu CAPTCHA ya me funciona sin problemas aunque a ciertas horas de la noche cuando soy voll damm 99% lo de sumar tambien cuesta lo suyo eh?

Les dedico un pequeño post en mi blog y va... te meto un enlaaace.... xDD

Enviar un comentario nuevo

El contenido de este campo se mantiene privado y no se mostrará públicamente.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Saltos automáticos de líneas y de párrafos.

Más información sobre opciones de formato

Image CAPTCHA
Enter the characters shown in the image. Ignore spaces and be careful about upper and lower case.

Afiliados:


I Love Your Blog

Otorgado por:Darlantan

Inicio de sesión


Todo el contenido mostrado ha sido obtenido libremente por la red. Las marcas indicadas son propiedad de sus legítimos dueños y se muestran a modo informativo de manera libre y voluntaria, sin intención publicitaria ni ánimo de lucro. Todo el material propio, y salvo que se indique lo contrario, se encuentra bajo licencia Creative Commons. Si tienes el Copyright de algún contenido o has detectado algna anomalia, por favor, infórmalo al correo undomain@gmail.com para ser corregido cuanto antes. El autor de esta Web no se hace responsable del contenido de terceras personas y de sites ajenos a este.

Powered by Drupal, an open source content management system