sql >> Database >  >> RDS >> Oracle

Oracle Analytic-functie voor minimale waarde in groepering

Ik denk dat de functie Rank() hier niet de juiste keuze voor is, om twee redenen.

Ten eerste is het waarschijnlijk minder efficiënt dan een op Min() gebaseerde methode.

De reden hiervoor is dat de query een geordende lijst van alle salarissen per afdeling moet bijhouden terwijl het de gegevens scant, en de rang zal later worden toegewezen door deze lijst opnieuw te lezen. Het is duidelijk dat bij het ontbreken van indexen die hiervoor kunnen worden gebruikt, u geen rang kunt toekennen totdat het laatste gegevensitem is gelezen, en het onderhoud van de lijst is duur.

De prestatie van de functie Rank() is dus afhankelijk van het totale aantal elementen dat moet worden gescand, en als het aantal voldoende is om de sortering op schijf te laten vallen, zullen de prestaties instorten.

Dit is waarschijnlijk efficiënter:

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

Deze methode vereist alleen dat de query een enkele waarde per afdeling behoudt van de minimale waarde die tot nu toe is aangetroffen. Als een nieuw minimum wordt aangetroffen, wordt de bestaande waarde gewijzigd, anders wordt de nieuwe waarde verwijderd. Het totale aantal elementen dat in het geheugen moet worden bewaard, is gerelateerd aan het aantal afdelingen, niet aan het aantal gescande rijen.

Het kan zijn dat Oracle een codepad heeft om te herkennen dat de rangorde in dit geval niet echt hoeft te worden berekend, maar ik zou er niet op wedden.

De tweede reden waarom je Rank() niet leuk vindt, is dat het gewoon de verkeerde vraag beantwoordt. De vraag is niet "Welke records hebben het salaris dat bovenaan staat als de salarissen per afdeling oplopend geordend zijn", maar "Welke records hebben het salaris dat het minimum is per afdeling". Dat maakt voor mij in ieder geval een groot verschil.



  1. Spring Boot:Jdbc javax.net.ssl.SSLException:inkomend sluiten voordat close_notify van peer wordt ontvangen

  2. Postgres:tijdstempels gebruiken voor paginering

  3. Automatisch failover beheren van de MySQL-database voor Moodle

  4. Kan mysqlclient niet installeren in virtualenv op nieuwe Mac