ASPNL logo (1 kb)
zaterdag 17 mei 2008




Microsoft MVP

.NET Codewise Community
<< vorige | overzicht | volgende >>

Data ophalen met Getrows

Door Charles Carroll
10 november 2000

Er zijn verschillende manieren om gegevens uit een database te halen. Veel mensen gebruiken code die er min of meer als volgt uit ziet:

'database openen
'recordset openen

Do Until rs.Eof
   strAdres = rs("Adres")
   strPcode = rs("Postcode")
   strPlaats = rs("Woonplaats")
   'meer operaties
   rs.MoveNext
Loop

'recordset sluiten
'database sluiten

Hoewel dit zeker werkt, is dit niet de meest efficiënte manier. Stel dat er 500 records in de recordset zitten met elk 3 velden, dan zou dit 1500 data aanvragen aan de database betekenen.
...nou ja, zo dramatisch is het niet, maar wel belangrijk om te zien dat dit problemen op kan leveren. Wat er eigenlijk gebeurt is dat er telkens een aantal records tegelijk wordt opgehaald. Hoeveel er tegelijk worden opgehaald, kan bepaald worden met rs.CacheSize. Zou je CacheSize op 50 zetten, dan worden de records in 10 aanvragen uit de database gehaald. Bij het opvragen van het eerste record worden records 1 tot en met 50 opgehaald. Zodra met MoveNext record 51 bereikt is, worden de volgende 50 opgehaald.

Een ander probleem met recordsets is dat terwijl je door een recordset heen loopt, de connectie met de database open blijft. Deze connectie is echter "duur", omdat er maar een beperkt aantal connecties bechikbaar is en deze ook extra geheugen kost. Het zou dus veel beter zijn om alle records in een keer op te halen, de database te sluiten en dan pas operaties op de gegevens uit te voeren.

De onderstaande code lost deze twee grote 'problemen' op.

'database openen
'recordset openen

MyArray = rs.GetRows

'recordset sluiten
'database sluiten

NumFields = UBound(MyArray, 1)
NumRows = UBound(MyArray, 2)
For i = 0 To NumRows
   strAdres = MyArray(0, i)
   strPcode = MyArray(1, i)
   strPlaats = MyArray(2, i)
   'meer operaties
Next

De bovenstaande code opent een database en een recordset en zet met de GetRows methode alle gegevens in een array, waarna de recordset en database gesloten worden. De array is een lokale variabele en kan dus makkelijk gemanipuleerd worden. Hiervoor hoeft niet telkens een aanvraag naar de database te gaan.
De rest van de code doet in feite hetzelfde als de eerdere code.

Oude gewoonten...
De meest voorkomende reden waarom mensen MoveNext gebruiken is omdat ze het zo geleerd hebben. Maar stel je nu eens voor dat 300 mensen tegelijk op een pagina komen met database operaties. Zonder GetRows of GetString zou er een veel zwaardere processor nodig zijn, omdat de scripts uitgevoerd worden in round-robin en hun context en data vaak moeten worden opgeslagen om alle aanvragen tegelijkertijd te kunnen afhandelen. Op een webserver wordt elke milliseconde die je verspilt vermenigvuldigd door mogelijk tienduizenden gebruikers (amazon.com, cnn.com). Je moet dus niet meer denken in traditionele een-voor-een operaties zoals MoveNext en operaties gebruiken die vele malen sneller zijn.

Zoals je kunt zien in het GetRows voorbeeld, kun je de recordset en de database connectie sluiten voordat je de data gaat gebruiken, bijvoorbeeld het doorlopen van de data en deze opmaken met een loop. Stel je voor dat het lezen van gegevens 1,5 seconde duurt en het opmaken van de gegevens 2,5 seconde, dan is de database 4 seconde geopend. Met GetRows duurt het lezen korter (door alles in één keer op te halen), misschien maar 0.75 seconde, waarna de recordset en de connectie gesloten zijn en teruggegeven worden aan de 'pool', voor een andere scripts om te gebruiken. Tijdens het opmaken van de gegevens zijn er bovendien geen locks die andere gebruikers in de weg zouden kunnen zitten.

Kyle Dyer schreef me... "Hoe zit het met Jscript?"
Hij was ook zo vriendelijk om me de resultaten van zijn research te sturen:

strSQL = "SELECT times FROM ...";
rs.Open(strSQL, conn);
recordSet.GetString(2,-1,"kolom-scheiding","rij-scheiding","null");

Parameters:

  1. string formaat: moet 2 zijn (verplicht in JScript)
  2. aantal rijen: -1 haalt ze allemaal (verplicht in JScript)
  3. scheiding tussen kolommen
  4. scheiding tussen rijen
  5. waarde voor 'null' waardes

Maakt het uit met kleine hoeveelheden gegevens?
JA!!!!!!!!
De SQL Server scripts op www.learnasp.com zijn razend snel. Ooit moest ik een listbox vullen met 9 items uit een Access database. Met MoveNext kreeg ik af en toe 90 seconden script-timeouts, terwijl GetString altijd werkte.
Het is dus mogelijk om 'zwakke' databases (zoals Access) te gebruiken op productie omgevingen met GetRows of GetString. Logischerwijs vermindert het de last op hoogwaardige database back-ends zoals SQL Server en Oracle, zodat voor deze ook minder extra geheugen en indexen nodig zijn.

Is er een snellere manier om gegevens op te halen?
Kijk eens naar "The Worlds Fastest Listbox", de enige manier om gegevens nog sneller op te halen.

© Charles Carroll (vertaling copyright ASPNL)

<< vorige | ^ naar boven | overzicht | volgende >>
copyright 2000-2007 ASPNL