# El costo de un query no depende solo de tus índices...

Level300

"El costo de un query no depende solo de tus índices, depende también de tu storage".

Te ha pasado que de pronto tienes el indice correcto, las estadísticas están recientes porque corriste dbms\_stats, el plan de ejecución lleva meses estable y sin embargo un día cualquiera...aparece el "misterio"...tu query que antes corría en serial ahora aparece con paralelismo que nadie pidió y un tiempo de ejecución elevado que oscila sin explicación aparente.

Revisas el "select" y no cambio, revisas indices todo ok, revisas estadísticas esta ok también , es decir revisas todo lo un dba aprende con el tiempo a revisar ante esta situacion; sin embargo el optimizador no mira solo eso, antes de decidir el grado de paralelismo mira la vista `DBA_RSRC_IO_CALIBRATE` y esta tabla no habla de indices ni de cardinalidad. habla de cuantos IOPs y cuantos MB/s tu storage puede brindarte, si alguien ejecuto calibrate\_io alguna vez en ese ambiente el optimizador ya tiene una opinión sobre tu hardware de disco.

**Y como funciona el mecanismo de paralelismo en este contexto?**

Cuando el parámetro `parallel_degree_policy` esta en AUTO o ADAPTATIVE no en MANUAL, el cual es el defecto en la mayoría de las instalaciones el optimizador evalúa el costo estimado de la operación y lo compara con el parámetro `parallel_min_time_threshold` , si es mayor Oracle decide paralelizar y para decir con cuantos procesos necesita saber la capacidad del storage, allí es donde aparece el calibrate\_io. Si nadie calibro nunca ese ambiente. el optimizador no se queda sin decidir, usa un valor de calibración por defecto, esto significa que un DOP "raro" puede tener 2 orígenes: una calibración que quedo desactualizada (el storage cambio y la calibración no) o el uso del default porque nunca se calibro.

**Y como realizamos la calibración?**

> Ejecutamos el procedimiento: DBMS\_RESOURCE\_MANAGER.CALIBRATE\_IO

\*\*Antes validamos si hay una ejecución previa:

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/3df4a629-d93e-40ca-bc66-f19889e046bc.png align="center")

Según vemos en la imagen no se ha ejecutado antes.

Procedemos a ejecutarlo:

> SET SERVEROUTPUT ON
> 
> DECLARE
> 
> lv\_iops PLS\_INTEGER;
> 
> lv\_mbps PLS\_INTEGER;
> 
> lv\_latency PLS\_INTEGER;
> 
> BEGIN
> 
> DBMS\_RESOURCE\_MANAGER.CALIBRATE\_IO ( num\_physical\_disks =>4, max\_latency => 20, max\_iops => lv\_iops, max\_mbps => lv\_mbps, actual\_latency => lv\_latency );
> 
> DBMS\_OUTPUT.PUT\_LINE('max\_iops = ' || lv\_iops); DBMS\_OUTPUT.PUT\_LINE('max\_mbps = ' || lv\_mbps); DBMS\_OUTPUT.PUT\_LINE('latency = ' || lv\_latency);
> 
> END;
> 
> /

Para ver el avance de la ejecución :

`SELECT status, calibration_time   FROM v$io_calibration_status;`

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/09af092d-70be-4bae-b45d-35ba7b50e698.png align="center")

Una vez finalizado procedemos a ver el resultado?

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/206af2a5-adc7-4751-bc94-4e2ac363a188.png align="center")

\*\*En mi ambiente de prueba demoró 3min y 4 seg, el tiempo en un ambiente de producción podría ser mas, asi que hay que hacerlo con precaución y en en periodos de poca carga para que no interfiera ni con la operación ni con la calibración.

Luego de finalizado la ejecución validamos que la vista tenga la información actualizada:

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/796db00a-ab56-410a-a9fd-6900c7a6c827.png align="center")

Con eso ya tenemos calibrado la bd a nivel de io.

Acá la descripción oficial de los campos de la documentación de oracle:

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/0130c759-a93e-4d20-9f19-38e8e175c276.png align="center")

Fuente: Oracle

\*\*Los parámetros para calibra son el numero de discos y la latencia que podemos tolerar en nuestros procesos, como referencia se pudo 20ms sin embargo esto puede variar según el contexto y necesidad de cada base de datos.

**Y para que que sirve Orion?**

Oracle también tiene una herramienta llamada Orion que ya viene como parte de los binarios de Oracle para medir la performance de los discos, un detalle con Orion es que se realiza sin existir aún base de datos y no se recomienda ejecutar sobre discos que ya tienen base de datos porque puede corromperla.

Entonces cuando usamos cual?

![](https://cdn.hashnode.com/uploads/covers/6a1ba5f97c924da4619cfa34/5c8f1c14-effc-4167-930e-7a6fd382909d.png align="center")

**Conclusión y recomendación:** El plan de ejecución no solo depende de tus índices y estadísticas, Auto DOP consulta `DBA_RSRC_IO_CALIBRATE`, así que revisa esa vista y tu `PARALLEL_DEGREE_POLICY` antes de buscar el problema en otro lado. Calibra solo si vas a usar Auto DOP documenta cuándo lo hiciste y vuelve a calibrar si el storage cambia, una calibración antigua podría ser peor que ninguna.
