[SQL2K] Records met kloktijden afwisselend 'nummeren'

Pagina: 1
Acties:

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ik heb een lijst met kloktijden van ons personeel. Mensen klokken bij aanvang van het werk, bij elke pauze en bij einde van de werkzaamheden.

Ik krijg de lijst met boekingen in een SQL Server 2k tabel. Deze tabel ziet er als volgt uit:

code:
1
2
3
4
5
6
7
8
9
Pasnummer   DatumTijd       IsEersteBoeking InOfUit
1234        13/05/2004 8:00 1
1234        13/05/2004 10:00    0
1234        13/05/2004 10:10    0   
1234        13/05/2004 12:00    0
3456        13/05/2004 5:00 1
3456        13/05/2004 8:00 0
3456        13/05/2004 8:15 0
3456        13/05/2004 12:00    0

etc. etc.

De kolom IsEersteBoeking is een bitveld dat aangeeft of de boeking beschouwd kan worden als de eerste boeking van de dienst.

De kolom InOfUit moet per record bijhouden of het een IN-boeking ('B') of een UIT-boeking ('E') is. Voor de records waar IsEersteBoeking op 1 staat is dit geen probleem. Dit is altijd een IN-boeking.

Het probleem dat ik heb is het updaten van de kolom InOfUit. Als we pasnummer 1234 als voorbeeld aanhouden is het eerste record een B, het volgende record (van 10:00 uur) een E, het volgende weer een B etc. etc. Voor het updaten van de kolom InOfUit heb ik de volgende query:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
UPDATE 
    TimeKeeperTussenTabel
SET
    InOfUit =  CASE(
            SELECT 
                Count(*) 
            FROM 
                TimeKeeperTussenTabel 
            WHERE 
                DatumTijd <= T1.DatumTijd AND Pasnummer = T1.Pasnummer AND DatumTijd > 
                (SELECT TOP 1 DatumTijd 
                FROM TimeKeeperTussenTabel 
                WHERE   DatumTijd < T1.DatumTijd 
                    AND IsEersteBoeking = 1 
                    AND Pasnummer =T1.Pasnummer ORDER BY DatumTijd DESC)
            )
        %2 WHEN 1 THEN 'E' ELSE 'B' END
FROM TimeKeeperTussenTabel T1


Simpelweg kijkt deze query naar het aantal boekingen tussen het laatste IsEersteBoeking record van het betreffende pasnummer en het betreffende record. Is dit even krijgt het huidige record een 'B', ander een 'E'. Zo krijgende records mooi om en om, op volgorde van de datum, een B en een E. Dit werkt op zich wel, alleen is de query behoorlijk traag bij veel records. Iemand een idee in welke richting ik zou kunnen denken voor een snellere methode?

Overigens zijn de indexen etc. allemaal goed ingesteld, daar hoeven jullie het niet te zoeken.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • faabman
  • Registratie: Januari 2001
  • Laatst online: 08-08-2024
Is het niet zo dat een boolean veld sneller is als een textveld :? Dan kun je van het veld InOfUit net zo goed een booleanveld maken...

Op zoek naar een baan als Coldfusion webdeveloper? Mail me!


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
faabman schreef op 13 mei 2004 @ 15:09:
Is het niet zo dat een boolean veld sneller is als een textveld :? Dan kun je van het veld InOfUit net zo goed een booleanveld maken...
Dat is nu niet aan de orde. Trouwens, het veld updaten zal niet zoveel tijd kosten.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • pistole
  • Registratie: Juli 2000
  • Laatst online: 08:46

pistole

Frutter

is het niet slimmer om een trigger te maken die een update voor je doet?

Ik frut, dus ik epibreer


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
pistole schreef op 13 mei 2004 @ 15:15:
is het niet slimmer om een trigger te maken die een update voor je doet?
Nee, de tabel wordt met een BULK INSERT gevuld. Ik wil er geen trigger op hebben.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

Als je het veld boolean maakt dan is het een optie om iets dergelijks te doen (pseudocode):
code:
1
2
3
4
5
6
7
8
UPDATE tabel AS t
SET IfOfUit = NOT IN (
   SELECT TOP 1 InOfUit
   FROM tabel
   WHERE gebruikerendatumgelijk
      AND datum < t.datum
   ORDER BY datum DESC
)

Heb het niet getest, en het zal wel Access specifieke SQL bevatten, maar je snapt het idee wel hoop ik. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
NMe84 schreef op 13 mei 2004 @ 15:30:
Als je het veld boolean maakt dan is het een optie om iets dergelijks te doen (pseudocode):
code:
1
2
3
4
5
6
7
8
UPDATE tabel AS t
SET IfOfUit = NOT IN (
   SELECT TOP 1 InOfUit
   FROM tabel
   WHERE gebruikerendatumgelijk
      AND datum < t.datum
   ORDER BY datum DESC
)

Heb het niet getest, en het zal wel Access specifieke SQL bevatten, maar je snapt het idee wel hoop ik. :)
Dit gaat volgens mij niet werken :) Omdat ik een groot aantal records tegelijk wil updaten is de waarde van de InOfUit kolom van de vorige record nog niet bekend. Dit zou kunnen, maar dan moet ik procedureel (bijv. met een cursor) door de code heenstappen. Of kijk ik er nu heel raar tegenaan?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Freee!!
  • Registratie: December 2002
  • Laatst online: 11:53

Freee!!

Trotse papa van Toon en Len!

Allemaal heel mooi, maar ik zie een klein praktisch probleem: Mensen willen nog wel eens vergeten te klokken. Als dat gebeurt, loopt de afwisseling niet meer goed.

The problem with common sense is that sense never ain't common - From the notebooks of Lazarus Long

GoT voor Behoud der Nederlandschen Taal [GvBdNT


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Mr. Liu schreef op 13 mei 2004 @ 15:38:
Allemaal heel mooi, maar ik zie een klein praktisch probleem: Mensen willen nog wel eens vergeten te klokken. Als dat gebeurt, loopt de afwisseling niet meer goed.
Je hebt helemaal gelijk, als dit gebeurt moet dit in de client applicatie aangepast worden. Dat is dan de verantwoording van de afdelingschef.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 10:40
P_de_B schreef op 13 mei 2004 @ 15:46:[...]Je hebt helemaal gelijk, als dit gebeurt moet dit in de client applicatie aangepast worden. Dat is dan de verantwoording van de afdelingschef.
siteuatieschetsje: de chef merkt op dat iemand niet heeft uitgeklokt voor de pauze van 11:00 uur, maar wel heeft ingeklokt nadien. Deze voegt dus een klok-record toe. Dan ga je dus alle andere records ook weer aanpassen? Want die zijn verkeerd door getelt.

Deze gegevens zijn in principe niet noodzakelijk om in de database op te slaan. Is het dan ook geen idee om dit pas bij het tonen van de gegevens te doen? Dan kun je namelijk heel eenvoudig om en om een B of een E tonen.

[ Voor 19% gewijzigd door djluc op 13-05-2004 15:53 ]


  • XtremeNova
  • Registratie: April 2002
  • Laatst online: 14-07-2025

XtremeNova

Alfa 145 Qv

Misschien een domme opmerking van iemand die er niet al te veel verstand van heeft, maar kun je niet een extra tabel aanmaken met daarin de nieuwe waarde voor ieder pasnummer? Is een kleindere tabel met minder regels, en ieder dag makkelijk te reseten zodat het 's morgens weer van voor afaan begint met B's en E's?

I like it red, with 150 bhp..


  • NMe
  • Registratie: Februari 2004
  • Laatst online: 24-05 14:53

NMe

Quia Ego Sic Dico.

P_de_B schreef op 13 mei 2004 @ 15:36:
Dit gaat volgens mij niet werken :) Omdat ik een groot aantal records tegelijk wil updaten is de waarde van de InOfUit kolom van de vorige record nog niet bekend. Dit zou kunnen, maar dan moet ik procedureel (bijv. met een cursor) door de code heenstappen. Of kijk ik er nu heel raar tegenaan?
Nee dat kan wel es kloppen wat je daar zegt. Bovendien past mijn query elk record aan, dus dat zou sowieso niet werken:

code:
1
2
3
4
5
1 B             1 E
2 E             2 B
3 B    ---->    3 E
4 E             4 B
5 B             5 E

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
djluc schreef op 13 mei 2004 @ 15:52:
[...]
siteuatieschetsje: de chef merkt op dat iemand niet heeft uitgeklokt voor de pauze van 11:00 uur, maar wel heeft ingeklokt nadien. Deze voegt dus een klok-record toe. Dan ga je dus alle andere records ook weer aanpassen? Want die zijn verkeerd door getelt.

Deze gegevens zijn in principe niet noodzakelijk om in de database op te slaan. Is het dan ook geen idee om dit pas bij het tonen van de gegevens te doen? Dan kun je namelijk heel eenvoudig om en om een B of een E tonen.
De gegevens opslaan is wel noodzakelijk, ik moet er ook mee rekenen (totale pauzetijd etc)
Misschien een domme opmerking van iemand die er niet al te veel verstand van heeft, maar kun je niet een extra tabel aanmaken met daarin de nieuwe waarde voor ieder pasnummer? Is een kleindere tabel met minder regels, en ieder dag makkelijk te reseten zodat het 's morgens weer van voor afaan begint met B's en E's?
Ja, dat is mijn alternatief. Dan kan ik mijn bestaande code gewoon gebruiken. Ik ben gewoon benieuwd of er een betere/snellere oplossing mogelijk is.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • beetle71
  • Registratie: Februari 2003
  • Laatst online: 14-05 15:52
P_de_B schreef op 13 mei 2004 @ 15:36:
[...]


Dit gaat volgens mij niet werken :) Omdat ik een groot aantal records tegelijk wil updaten is de waarde van de InOfUit kolom van de vorige record nog niet bekend. Dit zou kunnen, maar dan moet ik procedureel (bijv. met een cursor) door de code heenstappen. Of kijk ik er nu heel raar tegenaan?
Als de waarde van het vorige record niet bekend is ga je toch ook nooit kunnen weten wat de waarde in 'dit' record moet zijn. :? (of snap ik het dan niet helemaal..)

  • P_de_B
  • Registratie: Juli 2003
  • Niet online
beetle71 schreef op 13 mei 2004 @ 16:01:
[...]


Als de waarde van het vorige record niet bekend is ga je toch ook nooit kunnen weten wat de waarde in 'dit' record moet zijn. :? (of snap ik het dan niet helemaal..)
Jawel, door te kijken wat het bijhorende 'IsEersteRecord = 1' record is.

Wat ik bedoel met de vorige waarde is nog niet bekend is dat ik de update graag met 1 statement wil doen (setbased) omdat dat statement in een transactie zit kan ik niet tijdens het updaten kijken wat het vorige record is. Die is immers in dezelfde transacite geupdate en dus nog niet gecommit.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • d00d
  • Registratie: September 2003
  • Laatst online: 16-09-2025

d00d

geen matches

Je komt niet onder een subquery uit. Misschien is een cursor wel sneller dan deze SQL wanneer je gebruik maakt van het "WHERE CURRENT OF" statement. Zoniet dan is dit misschien beter, ik doe denk ik een select minder dan jij!

code:
1
2
3
4
5
6
7
8
update TimeKeeperTussenTabel
set InOfuit = CASE 
    (select COUNT(*) % 2
     from TimeKeeperTussenTabel T2
     where T2.DatumTijd < T1.DatumTijd
     and T1.Pasnummer = T2.Pasnummer)
when 0 then 'B' else 'E' end
from TimeKeeperTussenTabel T1

42.7 percent of all statistics are made up on the spot.


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
d00d schreef op 13 mei 2004 @ 16:30:
Je komt niet onder een subquery uit. Misschien is een cursor wel sneller dan deze SQL wanneer je gebruik maakt van het "WHERE CURRENT OF" statement. Zoniet dan is dit misschien beter, ik doe denk ik een select minder dan jij!

code:
1
2
3
4
5
6
7
8
update TimeKeeperTussenTabel
set InOfuit = CASE 
    (select COUNT(*) % 2
     from TimeKeeperTussenTabel T2
     where T2.DatumTijd < T1.DatumTijd
     and T1.Pasnummer = T2.Pasnummer)
when 0 then 'B' else 'E' end
from TimeKeeperTussenTabel T1
Je vergeet dat ik moet rekenen vanaf het in tijd meest nabije record waarbij het veld IsEersteRecord op 1 staat. Dat is ook de extra select die ik heb.

De code van jou telt ALLE voorgaande records van hetzelfde pasnummer.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 01:17
Je kunt een extra tabel maken waar je de 'inboekingen' bijhoudt. Op het moment dat mensen uitboeken verwijder je dat record. Je maakt dan een nieuw record in je 'boekingen' tabel met het moment van inboeken en het moment van uitboeken. Bepalen van eerste boeking en van de tijdsduur etc.. is dan erg eenvoudig geworden.
Bovendien kun je makkelijker zien of er ergens een in- of uitboek moment vergeten is.

[ Voor 8% gewijzigd door Sjaaky op 13-05-2004 17:04 ]


  • DukeMan
  • Registratie: Mei 2000
  • Niet online
Er vind blijkbaar een eindcontrole plaats. Is het niet een optie om, nadat het afdelingshoofd het een en ander gecontroleerd heeft, een afsluiting kunnen doen, waarin de juiste waarde in de kolom wordt gezet. Zo kan hij eerst eventuele records toevoegen om een correcte boeking te krijgen....

  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 01:17
shh verkeerde knopje :D

[ Voor 96% gewijzigd door Sjaaky op 13-05-2004 17:04 ]


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
Een aantal gedachten/opmerkingen:

1. heb je al overwogen om een temp table te gebruiken waarin je een autonumber kolom opneemt. Ik heb daar wel wat twijfels over ivm de bulk insert.
2. Je maakt gebruik van een correlated subquery, dwz je gebruikt in je subquery een referentie naar je hoofdquery en dan heb je een fors risico op performance problemen. Probeer hem eens te herschrijven zonder gebruik te maken van correlated subqueries.
3. Nog een andere mogelijkheid is om een while-loop te gebruiken waarbij je de eerste keer alle eerste boekingen van een dag met een 'B' vult, daarna alle tweede boekingen met een 'E' enz. Doordat de InOfUit kolom initieel niet gevuld is, kun je daar vrij eenvoudig op filteren. Zo gauw als er geen records meer ge-update zijn, ben je klaar.

Vooralsnog lijkt me optie 3 de beste.

[ Voor 53% gewijzigd door cameodski op 13-05-2004 18:14 ]

Never underestimate the power of


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Je kunt een extra tabel maken waar je de 'inboekingen' bijhoudt. Op het moment dat mensen uitboeken verwijder je dat record. Je maakt dan een nieuw record in je 'boekingen' tabel met het moment van inboeken en het moment van uitboeken. Bepalen van eerste boeking en van de tijdsduur etc.. is dan erg eenvoudig geworden.
Bovendien kun je makkelijker zien of er ergens een in- of uitboek moment vergeten is
Ik krijg de boeking in bulk binnen vanuit het kloksysteem. Dit gaat denk ik niet werken
Er vind blijkbaar een eindcontrole plaats. Is het niet een optie om, nadat het afdelingshoofd het een en ander gecontroleerd heeft, een afsluiting kunnen doen, waarin de juiste waarde in de kolom wordt gezet. Zo kan hij eerst eventuele records toevoegen om een correcte boeking te krijgen....
Dat gebeurt ook, maar alleen als er iets fout is gegaan met het boeken. Mensen die goed geklokt hebben moeten ook goed in het overzicht staan
1. heb je al overwogen om een temp table te gebruiken waarin je een autonumber kolom opneemt. Ik heb daar wel wat twijfels over ivm de bulk inse
Ik zie niet zo 1,2,3 wat ik daar mee zou kunnen?
2. Je maakt gebruik van een correlated subquery, dwz je gebruikt in je subquery een referentie naar je hoofdquery en dan heb je een fors risico op performance problemen. Probeer hem eens te herschrijven zonder gebruik te maken van correlated subqueries.
Dat klopt, dat is ook eigenlijk de voornaamste reden dat ik hem hier gepost heb. Ik zou alleen niet weten hoe ik de query zou kunnen herschrijven (zonder gebruik te maken van een cursor)
3. Nog een andere mogelijkheid is om een while-loop te gebruiken waarbij je de eerste keer alle eerste boekingen van een dag met een 'B' vult, daarna alle tweede boekingen met een 'E' enz. Doordat de InOfUit kolom initieel niet gevuld is, kun je daar vrij eenvoudig op filteren. Zo gauw als er geen records meer ge-update zijn, ben je klaar.
Hmmm, zoiets zou kunnen misschien. Heb je misschien (in pseudocode) een idee hoe?

Oops! Google Chrome could not find www.rijks%20museum.nl


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
P_de_B schreef op 14 mei 2004 @ 08:06:
[...]
Ik zie niet zo 1,2,3 wat ik daar mee zou kunnen?
[...]
Dat klopt, dat is ook eigenlijk de voornaamste reden dat ik hem hier gepost heb. Ik zou alleen niet weten hoe ik de query zou kunnen herschrijven (zonder gebruik te maken van een cursor)
[...]
Ik heb er niet heel diep over nagedacht, maar omdat je een count(*) gebruikte om het aantal tot de eerste boeking te bepalen, dacht ik dat je dat misschien ook wel via een autonumber in een temp table zou kunnen doen waardoor je dan wellicht je correlation uit je subquery zou kunnen halen, maar het was maar een gedachtensprong, dus ik weet niet of zoiets zou gaan werken.
Hmmm, zoiets zou kunnen misschien. Heb je misschien (in pseudocode) een idee hoe?
Ook hiervoor geldt dat het maar een ideetje was en ik dus niet weet of het ook echt werkt.
Ik ga nog proberen of ik je verder kan helpen.

Nog wel een vraagje. Is er elke dag weer een eerste boeking? Maw als ik een boeking heb die niet de eerste boeking is, kan ik er dan vanuit gaan, dat er eerder op dezelfde dag wel een eerste boeking is?

[ Voor 11% gewijzigd door cameodski op 14-05-2004 11:59 ]

Never underestimate the power of


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
cameodski schreef op 14 mei 2004 @ 11:41:
Nog wel een vraagje. Is er elke dag weer een eerste boeking? Maw als ik een boeking heb die niet de eerste boeking is, kan ik er dan vanuit gaan, dat er eerder op dezelfde dag wel een eerste boeking is?
Als het antwoord op deze vraag ja is, krijg je zoiets, denk ik (uit de losse pols dus):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
DECLARE @iteration int
DECLARE @rows  int

UPDATE TimeKeeperTussenTabel
SET    InOfUit = 'B'
WHERE  IsEersteBoeking = 1

SET @rows = 1
SET @iteration = 1
WHILE (@rows > 0) BEGIN
    UPDATE TimeKeeperTussenTabel
    SET    InOfUit = CASE (@iteration % 2) WHEN 0 THEN 'B' ELSE 'E' END
    FROM   TimeKeeperTussenTabel TA
    JOIN   ( SELECT T1.Pasnummer,
                    T2.DatumTijd AS DatumTijdEersteBoeking,
                    MIN (T1.DatumTijd) AS MinDatumTijd
             FROM   TimeKeeperTussenTabel T1
             JOIN   TimeKeeperTussenTabel T2 ON ((T2.Pasnummer = T1.Pasnummer)
                                                 AND (T2.IsEersteBoeking = 1)
                                                 AND (DATEDIFF (day, T2.DatumTijd, T1.DatumTijd) = 0)
                                                )
             WHERE  (T1.IsEersteBoeking = 0)
             AND    (ISNULL (T1.InOfUit, '') = '')
             GROUP BY T1.Pasnummer, T2.DatumTijd
           ) AS TB     ON ((TB.Pasnummer = TA.Pasnummer) AND (TB.MinDatumTijd = TA.DatumTijd))

    SET @rows = @@ROWCOUNT
    SET @iteration = @iteration + 1
END

Never underestimate the power of


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Nog wel een vraagje. Is er elke dag weer een eerste boeking? Maw als ik een boeking heb die niet de eerste boeking is, kan ik er dan vanuit gaan, dat er eerder op dezelfde dag wel een eerste boeking is?
Ja, elke dienst is er een eerste boeking. Dit kan ook de vorige dag zijn (bijv. als er 's avonds om 23:00 uur wordt begonnen door de nachtploeg)

Ik heb de code van je geprobeerd, en hij werkt heel goed :) Ik kon niet alle records controleren maar hij lijkt de goede resultaten te geven.

Op een tabel met 5500 records doet jouw code er 0:05 over, die van mij 0:12. Op een tabel met 250000 records doet jouw code er 1:04 over, die van mij 1:28. Een behoorlijke voortuitgang dus, die code van jou!

Nu zijn deze aantallen wel te hoog, de tabel wordt in principe elke dag geleegd. 1500 records zal meer in de buurt van de werkelijkheid zitten. Een echt levensgroot performanceprobleem was er dus niet maar ik vind het wel heel leuk om met dingen als deze te stoeien, en andere oplossingen van iemand anders te zien.

Wat uit jou code blijkt is dus wel dat een iteratieve oplossing sneller is/kan zijn dan een setbased oplossing met een correlated subquery.

Ik neem m'n petje af voor je query _/-\o_

Oops! Google Chrome could not find www.rijks%20museum.nl


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
P_de_B schreef op 14 mei 2004 @ 13:52:
[...]


Ja, elke dienst is er een eerste boeking. Dit kan ook de vorige dag zijn (bijv. als er 's avonds om 23:00 uur wordt begonnen door de nachtploeg)

Ik heb de code van je geprobeerd, en hij werkt heel goed :) Ik kon niet alle records controleren maar hij lijkt de goede resultaten te geven.
Volgens mij werkt mijn query niet als een dienst over twee dagen verspreid is. :? En als iemand meerdere diensten per dag draait, heb ik ook zo mijn twijfels. Dus eigenlijk ben ik een best wel verbaasd, dat ie zo goed werkt. Misschien dat je toch nog eens goed naar de resultaten moet kijken.
Op een tabel met 5500 records doet jouw code er 0:05 over, die van mij 0:12. Op een tabel met 250000 records doet jouw code er 1:04 over, die van mij 1:28. Een behoorlijke voortuitgang dus, die code van jou!

Nu zijn deze aantallen wel te hoog, de tabel wordt in principe elke dag geleegd. 1500 records zal meer in de buurt van de werkelijkheid zitten. Een echt levensgroot performanceprobleem was er dus niet maar ik vind het wel heel leuk om met dingen als deze te stoeien, en andere oplossingen van iemand anders te zien.

Wat uit jou code blijkt is dus wel dat een iteratieve oplossing sneller is/kan zijn dan een setbased oplossing met een correlated subquery.
Het verbaast me eigenlijk een beetje dat het verschil niet groter is, want correlated subqueries kunnen echt heel traag uitpakken. Had je al wel een index op InOfUit liggen? Misschien dat dat nog wat scheelt.
Overigens is mijn voorbeeld vooral setbased en per ongeluk ook nog een beetje iteratief.

Dit soort iteraties zijn ook handig bij deletes als er recursie in een tabel zit en er geen cascading delete mogelijk is. Het aantal iteraties is dan gelijk aan het aantal niveau's dat je recursieve structuur diep is. Alleen als er veel niveau's zijn, is het nog niet supersnel, maar altijd nog beter dan record voor record alles gaan uitzoeken.
Ik neem m'n petje af voor je query _/-\o_
Dank je.
offtopic:
Ik vind het erg leuk om over dit soort queries na te denken.

En om de performance van queries te verbeteren is het erg belangrijk om te weten en te begrijpen wat een RDBMS uitvoert.
Mijn ervaring is, dat execution plans daarbij heel erg nuttig zijn.
Ik heb net bijvoorbeeld een stored proc aangepast, waardoor die minstens 20 keer zo snel is geworden. Dat ding duurde gemiddeld zo'n 50 sec. en werd regelmatig gebruikt, dus die server vindt dat niet echt fijn. En dan te bedenken dat de stored proc netjes set based is, dus geen cursors oid.
Heb ongeveer een factor 10 versneld, doordat MSSQL een beetje dom deed: een tabel van 16 mln records joinen, terwijl 100 index lookups ook voldoende is.
En verder een factor 2 door een query met een stel left joins op te splitsen in meerdere queries met bijna alleen maar gewone inner joins.

Never underestimate the power of


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
cameodski schreef op 14 mei 2004 @ 14:41:
[...]

Volgens mij werkt mijn query niet als een dienst over twee dagen verspreid is. :? En als iemand meerdere diensten per dag draait, heb ik ook zo mijn twijfels. Dus eigenlijk ben ik een best wel verbaasd, dat ie zo goed werkt. Misschien dat je toch nog eens goed naar de resultaten moet kijken.
Hmm, zou kunnen. Heb ik idd nog niet gecontroloeerd.
[...]

Het verbaast me eigenlijk een beetje dat het verschil niet groter is, want correlated subqueries kunnen echt heel traag uitpakken. Had je al wel een index op InOfUit liggen? Misschien dat dat nog wat scheelt.
Een index op inofuit heb ik niet. Ik had verwacht dat dit niet echt zou helpen voor de performance omdat de kolom niet uit genoeg verschillende gegevens bestaat hoe heet dat ook al weer, is een woord voor
offtopic:
Ik vind het erg leuk om over dit soort queries na te denken.

En om de performance van queries te verbeteren is het erg belangrijk om te weten en te begrijpen wat een RDBMS uitvoert.
Mijn ervaring is, dat execution plans daarbij heel erg nuttig zijn.
Ik heb net bijvoorbeeld een stored proc aangepast, waardoor die minstens 20 keer zo snel is geworden. Dat ding duurde gemiddeld zo'n 50 sec. en werd regelmatig gebruikt, dus die server vindt dat niet echt fijn. En dan te bedenken dat de stored proc netjes set based is, dus geen cursors oid.
Heb ongeveer een factor 10 versneld, doordat MSSQL een beetje dom deed: een tabel van 16 mln records joinen, terwijl 100 index lookups ook voldoende is.
En verder een factor 2 door een query met een stel left joins op te splitsen in meerdere queries met bijna alleen maar gewone inner joins.
Nou, misschien is dit ook nog wel leuk:

De kolom IsEersteBoeking komt ook niet uit de klokken, maar is door een query geupdate. Ook deze query loopt niet over van snelheid.

Oorspronkelijk staat het IsEersteBoeking veld voor alle records op 0. Een record is een eerste record indien er min. 6 uur voorafgaand aan dat record geen boeking is geweest van het betreffende pasnummer. Indien dat het geval is, moet het IsEersteBoeking bitveld op 0 gezet worden.

Oops! Google Chrome could not find www.rijks%20museum.nl


  • cameodski
  • Registratie: Augustus 2002
  • Laatst online: 06-11-2023
P_de_B schreef op 14 mei 2004 @ 15:12:
[...]
Een index op inofuit heb ik niet. Ik had verwacht dat dit niet echt zou helpen voor de performance omdat de kolom niet uit genoeg verschillende gegevens bestaat hoe heet dat ook al weer, is een woord voor
Je bedoelt vast selectivity?
Ik denk dat je voor een groot gedeelte gelijk hebt, maar als er een paar mensen zijn die een beetje vaak hebben geklokt dan denk ik dat het wel wat op kan leveren, maar ik denk dat je daar idd geen wonderen van moet verwachten.
[...]
Nou, misschien is dit ook nog wel leuk:

De kolom IsEersteBoeking komt ook niet uit de klokken, maar is door een query geupdate. Ook deze query loopt niet over van snelheid.

Oorspronkelijk staat het IsEersteBoeking veld voor alle records op 0. Een record is een eerste record indien er min. 6 uur voorafgaand aan dat record geen boeking is geweest van het betreffende pasnummer. Indien dat het geval is, moet het IsEersteBoeking bitveld op 0 gezet worden.
Wat voor query gebruik je nu? En hoe lang duurt die? Ik verwacht trouwens niet dat je daar heel veel performance winst mee kunt behalen, omdat deze query me op het eerste gezicht niet zo ingewikkeld lijkt.

Never underestimate the power of


  • P_de_B
  • Registratie: Juli 2003
  • Niet online
Ik bedoel idd selectivity. Ik zal het nog wel even proberen. Wat betreft de query, die heb ik op m'n werk. Ik kokm hier maandag even op terug.

Oops! Google Chrome could not find www.rijks%20museum.nl

Pagina: 1