Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Função Oracle Analytic para valor mínimo no agrupamento


Eu acho que a função Rank() não é o caminho a seguir com isso, por dois motivos.

Em primeiro lugar, provavelmente é menos eficiente do que um método baseado em Min().

A razão para isso é que a consulta precisa manter uma lista ordenada de todos os salários por departamento à medida que varre os dados, e a classificação será atribuída posteriormente ao reler essa lista. Obviamente, na ausência de índices que possam ser aproveitados para isso, você não pode atribuir uma classificação até que o último item de dados seja lido, e a manutenção da lista é cara.

Portanto, o desempenho da função Rank() depende do número total de elementos a serem verificados e, se o número for suficiente para que a classificação seja derramada no disco, o desempenho será reduzido.

Isso provavelmente é mais 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 requer apenas que a consulta mantenha um único valor por departamento do valor mínimo encontrado até o momento. Se um novo mínimo for encontrado, o valor existente será modificado, caso contrário, o novo valor será descartado. O número total de elementos que devem ser mantidos na memória está relacionado ao número de departamentos, não ao número de linhas verificadas.

Pode ser que o Oracle tenha um caminho de código para reconhecer que o Rank realmente não precisa ser computado neste caso, mas eu não apostaria nisso.

A segunda razão para não gostar de Rank() é que ele apenas responde à pergunta errada. A questão não é "Quais registros têm o salário que é o primeiro ranking quando os salários por departamento são ordenados de forma ascendente", é "Quais registros têm o salário que é o mínimo por departamento". Isso faz uma grande diferença para mim, pelo menos.