La cláusula QUALIFY filtra el resultado después de calcular la función analítica.
Oracle posiciona QUALIFY como el equivalente analítico de HAVING, pero aplicado a funciones window.
Este tipo de mejora suele pasar desapercibida frente a AI Vector Search, pero impacta directamente el diseño de consultas complejas, especialmente en:
A nivel del plan de ejecución podemos ver que ambas consultas a pesar de brindar el mismo resultado, no son equivalentes de cara al optimizador, aunque a nivel de costo, son equivalentes.
[oracle@oracle-server-26ai ~]$ sqlplus /nolog
SQL*Plus: Release 23.26.1.0.0 - Production on Mon Apr 6 02:50:48 2026
Version 23.26.1.0.0
Copyright (c) 1982, 2025, Oracle. All rights reserved.
SQL> connect einsten/oracle@pdb1
Connected.
SQL> set linesize 200
SQL> set pagesize 20
SQL> explain plan for
2 SELECT *
FROM (
SELECT employee_id,
department_id,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) rn
FROM hr.employees
)
WHERE rn = 1;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------------
Plan hash value: 2698234872
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 220 | 4 (25)| 00:00:01 |
|* 1 | VIEW | | 11 | 220 | 4 (25)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK| | 107 | 1177 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMPLOYEES | 107 | 1177 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("RN"=1)
2 - filter(ROW_NUMBER() OVER ( PARTITION BY "DEPARTMENT_ID" ORDER BY
"SALARY" DESC )<=1)
17 rows selected.
SQL> explain plan for
2 SELECT employee_id,
department_id,
ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY salary DESC) rn
FROM hr.employees
QUALIFY rn = 1;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------------
Plan hash value: 2698234872
--------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 11 | 242 | 4 (25)| 00:00:01 |
|* 1 | VIEW | | 11 | 242 | 4 (25)| 00:00:01 |
|* 2 | WINDOW SORT PUSHED RANK| | 107 | 1177 | 4 (25)| 00:00:01 |
| 3 | TABLE ACCESS FULL | EMPLOYEES | 107 | 1177 | 3 (0)| 00:00:01 |
--------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("from$_subquery$_002"."sys_qualify$_h$_predex$_0"=TRUE)
2 - filter(ROW_NUMBER() OVER ( PARTITION BY "DEPARTMENT_ID" ORDER BY
"SALARY" DESC )<=1)
17 rows selected.
SQL>
Si observamos detenidamente, veremos que con el uso de la cláusula "QUALITY" el optimizador realiza un filtro en la creación de la vista con "filter("from$_subquery$_002"."sys_qualify$_h$_predex$_0"=TRUE)
No hay comentarios:
Publicar un comentario
Te agradezco tus comentarios. Te esperamos de vuelta.