sql >> Base de Datos >  >> RDS >> Oracle

Función Oracle Analytic para el valor mínimo en la agrupación

Creo que la función Rank() no es el camino a seguir con esto, por dos razones.

En primer lugar, probablemente sea menos eficiente que un método basado en Min().

La razón de esto es que la consulta debe mantener una lista ordenada de todos los salarios por departamento a medida que escanea los datos, y luego se asignará el rango al volver a leer esta lista. Obviamente, en ausencia de índices que puedan aprovecharse para esto, no puede asignar un rango hasta que se haya leído el último elemento de datos, y el mantenimiento de la lista es costoso.

Por lo tanto, el rendimiento de la función Rank() depende del número total de elementos que se analizarán y, si el número es suficiente para que la ordenación se derrame en el disco, el rendimiento colapsará.

Esto es probablemente más eficiente:

select dept,
       emp,
       salary
from
       (
       SELECT dept, 
              emp,
              salary,
              Min(salary) Over (Partition By dept) min_salary
       FROM   mytable
       )
where salary = min_salary
/

Este método solo requiere que la consulta mantenga un único valor por departamento del valor mínimo encontrado hasta el momento. Si se encuentra un nuevo mínimo, se modifica el valor existente; de ​​lo contrario, se descarta el nuevo valor. La cantidad total de elementos que deben mantenerse en la memoria está relacionada con la cantidad de departamentos, no con la cantidad de filas escaneadas.

Podría ser que Oracle tenga una ruta de código para reconocer que el rango realmente no necesita calcularse en este caso, pero no apostaría por eso.

La segunda razón por la que no me gusta Rank() es que simplemente responde la pregunta incorrecta. La pregunta no es "¿Qué registros tienen el salario que es el primero en la clasificación cuando los salarios por departamento están ordenados de forma ascendente", es "Qué registros tienen el salario que es el mínimo por departamento". Eso hace una gran diferencia para mí, al menos.