[ORACLE SQL] SQL maar één keer uitvoeren

Pagina: 1
Acties:
  • 271 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Altijd een beetje schimmig die titels maar ik leg 't eventjes uit hieronder.

Ik heb een view op een vrij grote tabel in Oracle 9. Hiervan moet ik per categorie een telling geven en een percentage van die categorie t.o.v. het totaal.
Op zich geen probleem voor mij.

Zonder percentageberkening loopt ie in ongeveer een halve seconde (soms ietsje meer):
code:
1
2
3
select CATEGORIE, COUNT(*) 
   from VIEWNAAM 
   group by CATEGORIE


Het veld CATEGORIE is overigens geen databaseveld, maar een waarde die tijdens uitvoering wordt bepaald in de view (gecategoriseerde aantal werkdagen: <20 dagen, 20-30 dagen, 30 dagen en meer).

Maar om de percentages te bepalen moet ik die view dus nogmaals aanroepen om eerst het totaal aantal records uit die view te krijgen. In het explain plan zie je dat ook terug overigens: de view wordt twee keer aangeroepen, wat de doorlooptijd verhoogt naar iets over de 1 seconde.

code:
1
2
3
select CATEGORIE, COUNT(*), COUNT(*)/TOTAALATL as PERCENTAGE
   from VIEWNAAM, (COUNT(*) as TOTAALATL from VIEWNAAM)  
   group by CATEGORIE


Ik heb wat zitten klooien met Max(ROWID) ipv TOTAALATL. Werkt wel sneller, maar die geeft vreemde getallen, dus da's ook geen optie.

Waarom dit getob? Dit is één van de (op dit moment) zes queries op die view ('t worden er nog meer). Ik kan dus kiezen tussen 3 seconden wachten voor de gebruiker en meer dan 6 seconden wachten. Dat laatste is voor mij niet meer acceptabel om de gebruikers voor te schotelen.

Is wat ik nou wil onmogelijk (dus percentageberekening doen en de view maar één keer benaderen) en moet ik me er maar bij neerleggen? Of heb ik verkeerd gezocht op internet? Want daar vind ik alleen maar SQL%ROWCOUNT (die ik volgens mij niet kan gebruiken in SQL) en de normale COUNT.
De database is niet van mij, dus daar mag ik verder ook niet teveel in rommelen...

Hopelijk is het allemaal een beetje duidelijk hier boven.

Vlinders moet je volgen, niet vangen...


Acties:
  • 0 Henk 'm!

  • Sepio
  • Registratie: Oktober 2007
  • Laatst online: 12:18
Hoi,

Als je een ANALYTISCHE functie gebruikt dan kan dit zonder problemen. Analytische functies zijn erg handig om berekeningen uit te voeren zonder de data opnieuw op te halen. Oracle kan hiervoor kijken naar de opgehaalde records onderling.

Een voorbeeld kun je hieronder vinden. Ik heb in plaats van jouw view een selectie gedaan uit USER_OBJECTS zodat ik data had om te testen.

SQL:
1
2
3
4
5
6
7
8
9
select CATEGORIE, AANTAL / sum (AANTAL) over () *100 as PERCENTAGE
from (
    select CATEGORIE, COUNT(*) as AANTAL
    from (
         select object_type as categorie 
         from user_objects
    )   
    group by CATEGORIE
)

Acties:
  • 0 Henk 'm!

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
Hé dank je. Ik ga ff kijken of het hiermee een beetje sneller wil gaan allemaal. En dan laat ik 't nog wel weten!

[Edit ff later]
En dit wordt idd maar één keer uitgevoerd en binnen de halve seconde, super!
Hier moet ik het mee redden en mee verder kunnen. Tnkx!

[ Voor 40% gewijzigd door PaulZ op 12-10-2007 13:17 ]

Vlinders moet je volgen, niet vangen...


Acties:
  • 0 Henk 'm!

  • Sepio
  • Registratie: Oktober 2007
  • Laatst online: 12:18
In een van de oude versies van Oracle (ik ben vergeten welke) maakte het uit of je een COUNT(*) of een COUNT(1) deed. De eerste zorgde in het execution plan voor een full table scan de andere deed alles via een index. Misschien levert dit ook nog wat extra tijdwinst op.

Is het misschien verstandig om van je categorie een function based index te maken. Misschien is alles dan nog sneller te benaderen.

Acties:
  • 0 Henk 'm!

  • PaulZ
  • Registratie: Augustus 2004
  • Laatst online: 21-05-2024
@Sepio: heb de count opties ook nog even geprobeerd, maar dat is nanoseconden-werk.
Die function based index is er volgens wat ik zo snel heb nagelezen alleen voor tabel columns.
Mijn veld CATEGORIE is het resultaat van een functie (input=aantal werkdagen, output=categorie), dus da's denk ik niet zo bruikbaar voor mij. Maar bedankt voor de tip. Kan ik misschien elders nog wel gebruiken.

Vlinders moet je volgen, niet vangen...