![[26ai] Funciones Analíticas-Qualify](https://cdn.hashnode.com/uploads/covers/65605419d28f19cc44df7ef1/6b069c59-7a4c-48c8-afbd-1dd7fd199f38.png)
En el artículo de hoy, vamos a ver otro gran cambio para hacernos la vida más fácil a los DBA y desarrolladores, es la clausula qualify. Pero, ¿Para que sirve?
Los que hacemos diariamente uso de las funciones analíticas utilizando la función Row_Number para quedarnos con el mejor resultado dentro de un grupo de datos, acabamos definiendo una subquery.
Está clausula filtra los resultados de las funciones analíticas dentro de la misma sentencia, sin necesidad de definir subquerys, consiguiendo una mayor eficiencia.
Un ejemplo, supongamos que estamos consultando las vistas de AWR, y queremos consultar para el mes actual, las consultas con mayor BUFFER_GETS_DELTA a nivel de snap.
En versiones anteriores a 26ai tendríamos que definirlo del siguiente modo:
SQL>
With My_Snaps As (
SELECT snap_id,INSTANCE_NUMBER,begin_interval_time
FROM dba_hist_snapshot
WHERE extract(Year from begin_interval_time) = extract(year from sysdate)
And extract(Month from begin_interval_time) = extract(Month from sysdate)
)
SELECT
METRICA,
day,
db_name,
Instance,
SQL_ID,
plan_hash_value,
INST,
EXEC,
rows_,
elap,
BUFFER_GETS_DELTA
FROM (
SELECT
'GETS' AS METRICA,
extract(day from begin_interval_time) day,
Sys_Context('USERENV', 'DB_NAME') db_name,
Sys_Context('USERENV','INSTANCE_NAME') Instance,
a.SNAP_ID,
a.SQL_ID,
a.plan_hash_value,
a.INSTANCE_NUMBER INST,
a.EXECUTIONS_DELTA EXEC,
a.ROWS_PROCESSED_DELTA rows_,
a.ELAPSED_TIME_DELTA elap,
a.BUFFER_GETS_DELTA,
ROW_NUMBER() OVER (
PARTITION BY a.SNAP_ID
ORDER BY a.BUFFER_GETS_DELTA DESC nulls last) As ORDEN
FROM DBA_HIST_SQLSTAT a,My_Snaps b
WHERE 1 = 1
And A.Snap_Id = b.Snap_Id
And A.INSTANCE_NUMBER = B.INSTANCE_NUMBER
And PARSING_SCHEMA_NAME != 'SYS'
)
Where ORDEN = 1
fetch first 20 rows Only;
Con este resultado:
En 26ai podemos conseguir el mismo resultado usando la cláusula QUALIFY.
SQL>
With My_Snaps As (
SELECT snap_id,INSTANCE_NUMBER,begin_interval_time
FROM dba_hist_snapshot
WHERE extract(Year from begin_interval_time) = extract(year from sysdate)
And extract(Month from begin_interval_time) = extract(Month from sysdate)
)
SELECT
'GETS' AS METRICA,
extract(day from begin_interval_time) day,
Sys_Context('USERENV', 'DB_NAME') db_name,
Sys_Context('USERENV','INSTANCE_NAME') Instance,
a.SNAP_ID,
a.SQL_ID,
a.plan_hash_value,
a.INSTANCE_NUMBER INST,
a.EXECUTIONS_DELTA EXEC,
a.ROWS_PROCESSED_DELTA rows_,
a.ELAPSED_TIME_DELTA elap,
a.BUFFER_GETS_DELTA,
ROW_NUMBER() OVER (
PARTITION BY a.SNAP_ID
ORDER BY a.BUFFER_GETS_DELTA DESC nulls last) As ORDEN
FROM DBA_HIST_SQLSTAT a,My_Snaps b
WHERE A.Snap_Id = b.Snap_Id
And A.INSTANCE_NUMBER = B.INSTANCE_NUMBER
And PARSING_SCHEMA_NAME != 'SYS'
qualify ORDEN = 1
fetch first 20 rows Only;
Con este resultado:
Como podemos observar ambos output son idénticos sin necesidad de hacer una subquery, mejorando al eficiencia así como la legibilidad de la misma.
Espero que os guste. ¡Nos vemos en el próximo artículo!
About the author
Ingeniero informático, Oracle ACE, DBA y Arquitecto OCI, con más de 15 años de experiencia en plataformas Oracle. Certificado en OCI Certified Architect Professional y OCI Migration and Integration Certified Professional.
Comments
Join the discussionNo comments yet. Be the first to comment.



