En el post anterior Análisis de AWR – Particiones que no se acceden correctamente evaluamos el rendimiento en horas de trabajo, y ahora vamos a estudiar la carga en fin de semana para ver si hay algún punto mejorable
Igual que hicimos en el caso anterior, vemos que es una base de datos single instance que sin arquitectura CDB
Si miramos como ha estado la CPU durante ese fin de semana, vemos que tenemos mucha memoria libre con un 95,1 %Idle, es decir menos carga incluso que durante la semana: menos de un 4% de carga de usuario.
A nivel de eventos de espera “Top 10 Foreground Events by Total Wait Time” no vemos tampoco nada anómalo. En esta lista, el evento DB CPU es el primer evento, con lo que el funcionamiento que hay en la base de datos parece correcto
Hasta aquí podemos decir que el funcionamiento de la base de datos durante ese fin de semana ha sido relajado.
No obstante, si entramos en la parte de sentencias SQL y no a nivel global vemos algo que nos llama la atención, una consulta con más de 5.000.000 millones de lecturas de bloque, !una burrada!
Vamos a revisar esa sentencia en detalle por ver si tenemos algún problema a nivel de SQL: que esté mal escrito, problemas con las estadísticas, no se esté atacando bien a los datos…etc.
Para analizar esa consulta vamos a generar el AWR de sentencia de esa consulta utilizando el SQL_ID que hemos localizado en el apartado de “SQL ordered by Gets”, es decir, SQL ordenado por lectura de bloques en memoria.
Aquí vemos que el tiempo total de la sentencia no tarda mucho a penas llega el minuto (Elapsed Time 51.900 segundos) pero el valor de lectura de bloques es muy alto: 83Gb.
Otra cosa interesante que nos dice el informe es que se está aplicando un dynamic sampling, es decir, estadísticas al vuelo porque hay alguna tabla que no tiene estadísticas frescas. Habría que revisar cada tabla utilizada y comprobar por cuales se están generando.
Para ver si las estadísticas están frescas, es decir, se corresponden con la volumetría actual de los objetos, hay que ir a la tabla ALL_TAB_STATISTICS y el campo STALE_STATS nos dice si se necesita pasar estadísticas para esa tabla.
Al revisar las estadísticas de las tablas utilizadas en la consulta, vemos que la única que no tiene estadísticas frescas es una tabla temporal.
Analizamos vemos la estimación y los recursos consumidos
Y vemos que se realizan un montón de productos cartesianos.
Desde el punto de vista del optimizador, el join de estas tablas cuando sólo tienen una única fila se realiza de forma más eficiente con un producto cartesiano, es decir, combinar todos con todos o, lo que sería en este caso, combinar únicamente una fila con otra. El problema se produce cuando en la práctica la estimación de una única fila no se corresponde con el volumen real, y se producen combinaciones cartesianas de miles o millones de filas.
En el siguiente capitulo veremos como optimizar la consulta para hacer desaparecer esos productos cartesianos.