Ik heb een csv files welke afhankelijk van eerdere data zo'n 35 a 40MB groot is (niet heel bijzonder groot lijkt mij). Dit bestand bestaat uit 4 kolommen en z'n 400k regels.
Ik heb nu 2 varianten van verwerking gemaakt maar de performance vind ik gewoon zeer matig.
Code volgt onder deze tekst..
Variant 1 maakt gebruik van import-csv functie wat al voor de nodige vertraging zorgt voordat het echt begint te verwerken. En uiteindelijk duurt de verwerking iets meer dan een uur
Variant 2 gebruikt ik streamreader, de start is dan al sneller maar ook al schrijf ik in die variant per 800 regels de data weg naar de SQL database duurt het geheel nog steeds 50 minuten. (Op AMD Ryzen 5 Pro 2500U met 8GB)
Dus ook niet echt de performance boost waar ik op zat te hopen.
variant 1 (import-csv)
Variant 2: (streamreader)
Het CSV bestand waar de data uitkomt ziet er als volgt uit:
De reden dat ik de if ($Rowcount -eq 0) erin heb staan is dat de streamreader niet de eerste regel wil overslaan en bij import-csv wordt deze gelijk als kolom naam gebruikt. Deze data naar de SQL database sturen gaat niet goed als er bijvoorbeeld een datum wordt verwacht.
Nu heb ik ook gelezen dat je een CSV in een dataset kan laden maar zal dat echt de nodige performance boost geven voordat ik daar nog een andere test variant van ga maken?
Ik heb nu 2 varianten van verwerking gemaakt maar de performance vind ik gewoon zeer matig.
Code volgt onder deze tekst..
Variant 1 maakt gebruik van import-csv functie wat al voor de nodige vertraging zorgt voordat het echt begint te verwerken. En uiteindelijk duurt de verwerking iets meer dan een uur
Variant 2 gebruikt ik streamreader, de start is dan al sneller maar ook al schrijf ik in die variant per 800 regels de data weg naar de SQL database duurt het geheel nog steeds 50 minuten. (Op AMD Ryzen 5 Pro 2500U met 8GB)
Dus ook niet echt de performance boost waar ik op zat te hopen.
variant 1 (import-csv)
Visual Basic .NET:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| $TotalRows = 0 $reader = New-Object IO.StreamReader "$global:Logdir\Newfile.csv" while($reader.ReadLine() -ne $null){ $TotalRows++ } $reader.Dispose() $actlog = Import-CSV "$global:Logdir\Newfile.csv" ForEach ($row in $actlog) { $Rowcount=++ $locatie = $row.('ai').Split(':')[1] #headers are created by previous export $oproeppunt = $row.('aj').Split(':')[1] $tijdstip = $row.('j').Split(':')[1] #2019-06-25 09.30.38 must be change to: 2019-06-25 09:30:38 $tijdstip = $tijdstip.replace('.',':') $Status = $row.('ab').Split(':')[1] LogToevoegen $global:pnummer $locatie $oproeppunt $tijdstip $Status Write-Progress -Activity "Processing lines from CSV.." -PercentComplete (($Rowcount*100)/$TotalRows) -Status "$(([math]::Round((($rowcount)/$TotalRows * 100),0))) %" } #end foreach filling database log "All done!" |
Variant 2: (streamreader)
Visual Basic .NET:
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
30
31
32
33
34
35
36
37
38
39
| $TotalRows = 0 $rowcount = 0 $sqlrowcounter = 0 $reader = New-Object IO.StreamReader "$global:Logdir\Newfile.csv" while($reader.ReadLine() -ne $null){ $TotalRows++ } $reader.BaseStream.Position = 1 while(($Tempdata = $reader.ReadLine()) -ne $null){ if ($rowcount -eq 0) {$rowcount = $rowcount + 1} else { $splitvar = '","' $row = $Tempdata -Split($splitvar) if ($sqlrowcounter -eq 0) { $SQLstring=''} #end if if ($sqlrowcounter -ne 0) { $SQLstring = $SQLstring + ','} $sqlrowcounter= $sqlrowcounter + 1 $Rowcount= $Rowcount + 1 $locatie = $row[0].Split(':')[1] $oproeppunt = $row[1].Split(':')[1] $tijdstip = $row[2].Split(':')[1] #2019-06-25 09.30.38 must be change to: 2019-06-25 09:30:38 $tijdstip = $tijdstip.replace('.',':') $Status = $row[3].Split(':')[1] $Status = $Status.Substring(0, $Status.Length -1) if (($null -ne $locatie) -and ($null -ne $oproeppunt) -and ($null -ne $tijdstip) -and ($null -ne $Status)){ $SQLstring = $SQLstring + "($global:pnummer, '$locatie', '$oproeppunt', '$tijdstip', '$Status')" } if ($sqlrowcounter -eq 800){ LogToevoegenBatch $SQLstring $sqlrowcounter = 0 } Write-Progress -Activity "Processing lines from CSV.." -PercentComplete (($Rowcount*100)/$TotalRows) -Status "$(([math]::Round((($rowcount)/$TotalRows * 100),0))) %" } #end if rowcount = 0 } #end while $reader.Dispose() $reader.Close() If ($sqlrowcounter -gt 0){ LogToevoegenBatch $SQLstring } #needed write the last part to the database "All done!" |
Het CSV bestand waar de data uitkomt ziet er als volgt uit:
code:
1
2
3
4
5
6
7
8
| "ai","aj","j","ab" "Text:C477P.","Name:C477P","Time:2020-01-31 23.10.36","NI_State:Set" "Text:B343P","Name:B343P.","Time:2020-01-31 23.10.52","NI_State:Set" "Text:B343P.","Name:B343P","Time:2020-01-31 23.10.52","NI_State:Clear" "Text:B343P","Name:B343P.","Time:2020-01-31 23.10.53","NI_State:Clear" "Text:C477P","Name:C477P.","Time:2020-01-31 23.11.50","NI_State:Set" "Text:C477P.","Name:C477P","Time:2020-01-31 23.11.51","NI_State:Clear" "Text:C477P","Name:C477P.","Time:2020-01-31 23.11.51","NI_State:Clear" |
De reden dat ik de if ($Rowcount -eq 0) erin heb staan is dat de streamreader niet de eerste regel wil overslaan en bij import-csv wordt deze gelijk als kolom naam gebruikt. Deze data naar de SQL database sturen gaat niet goed als er bijvoorbeeld een datum wordt verwacht.
Nu heb ik ook gelezen dat je een CSV in een dataset kan laden maar zal dat echt de nodige performance boost geven voordat ik daar nog een andere test variant van ga maken?
Taal fouten inbegrepen ;)
Mijn AI Art YouTube kanaal