Dopo aver provato vari metodi di importazione di un file dati in formato testo in un database, come meglio descritto nel mio precedente post Importare un file di testo in SQL Server (Ce ed Express), ho effettuato anche le prove con SqlBulkCopy.
Questi i risultati:
Using SQL Server Express Edition
====================================================================
BulkCopy step 1 of 2 (read textfile to a DataTable)..: 00.01.22.1578
BulkCopy step 2 of 2 (write DataTable to the DB).....: 00.01.34.4933
--------------------------------------------------------------------
BulkCopy total elapsed time..........................: 00.02.56.6511
Deleting imported table..............................: 00.01.28.9116
BulkCopy from textFileDataReader (batch size 0)......: 00.02.59.3999
Deleting imported table..............................: 00.01.18.3308
BulkCopy from textFileDataReader (batch size 100.000): 00.02.40.1774
Deleting imported table..............................: 00.00.55.0827
BulkCopy from textFileDataReader (batch size 10.000).: 00.01.26.5775
Deleting imported table..............................: 00.00.29.8098
BulkCopy from textFileDataReader (batch size 1.000)..: 00.01.35.7437
Deleting imported table..............................: 00.00.21.8374
BulkCopy from textFileDataReader (batch size 100)....: 00.02.59.1883
Da cui deriva che:
Importare in una DataTable e poi fare la bulk copy equivale a fare la bulk copy passandogli direttamente lo stesso iDataReader utilizzato per riempire la DataTable (2' 56" Vs. 2' 59");
Di default l'istanza sqlBulkCopy ha la proprietà BatchSize impostata a zero, ossia raggruppa tutte le operazioni di inserimento in un unico comando sql insert (e bisogna settare la proprietà BulkCopyTimeout a un numero di secondi sufficiente per completare l'operazione), ma non è sempre l'imposazione ottimale. Dalle prove fatte, in questo caso, il risultato migliore si ottiene con batch size 10.000 .
Riassumendo le varie prove fatte abbiamo:
Using SQL Server Compact Edition
====================================================================
Import from text file (modify cmd each iteration)....: 00.11.29.9476
Deleting imported table..............................: 00.00.43.3449
Import from text file (with param and cmd prepare)...: 00.06.05.5234
Deleting imported table..............................: 00.00.43.6101
Transactional import from text file..................: 00.06.23.0232
Transactional deleting imported table................: 00.00.43.2467
Direct table import from text file (ResultSet).......: 00.06.22.4188
Deleting imported table..............................: 00.00.43.3742
Using SQL Server Express Edition
====================================================================
Import from text file (modify cmd each iteration)....: 00.37.19.1644
Deleting imported table..............................: 00.01.49.0421
Import from text file (with param and cmd prepare)...: 00.32.54.1606
Deleting imported table..............................: 00.00.40.2665
Transactional import from text file..................: 00.08.30.1257
Transactional deleting imported table................: 00.00.17.2543
BulkCopy step 1 of 2 (read textfile to a DataTable)..: 00.01.22.1578
BulkCopy step 2 of 2 (write DataTable to the DB).....: 00.01.34.4933
--------------------------------------------------------------------
BulkCopy total elapsed time..........................: 00.02.56.6511
Deleting imported table..............................: 00.01.28.9116
BulkCopy from textFileDataReader (batch size 0)......: 00.02.59.3999
Deleting imported table..............................: 00.01.18.3308
BulkCopy from textFileDataReader (batch size 100.000): 00.02.40.1774
Deleting imported table..............................: 00.00.55.0827
BulkCopy from textFileDataReader (batch size 10.000).: 00.01.26.5775
Deleting imported table..............................: 00.00.29.8098
BulkCopy from textFileDataReader (batch size 1.000)..: 00.01.35.7437
Deleting imported table..............................: 00.00.21.8374
BulkCopy from textFileDataReader (batch size 100)....: 00.02.59.1883
I risultati suddetti sono comunque da prendere con le molle perchè ho ancora dei dubbi:
- Che parte gioca il Garbage Collector nei primi metodi? (Probabilmente si potrebbe ottenere dei risparmi ri-utilizzando una string builder)
- Perchè abbiamo risultati notevolmente differenti nelle varie chiamate a "Deleting imported table" ?
Comunque, per chi volesse vederli, i sorgenti sono in questo post (che non ho "affisso" al muro UgiDotNet per non dar fastidio).
Buone feste!