Donc, je travaille sur une base de données que je vais ajouter à mes futurs projets comme une sorte de db de support, mais je vais avoir un peu de problème avec lui, en particulier les journaux.Sql Server 2008 Réglage avec des transactions importantes (700k + lignes/transaction)
La base de données doit être mise à jour une fois par mois. La table principale doit être purgée puis rechargée à partir d'un fichier CSV. Le problème est que Sql Server va générer un journal pour ce qui est grand MEGA. J'ai réussi à le remplir une fois, mais je voulais tester tout le processus en le purgeant et en le remplissant ensuite.
C'est quand j'obtiens une erreur que le fichier journal est rempli. Il passe de 88 Mo (après réduction par le biais du plan de maintenance) à 248 Mo, puis interrompt complètement le processus et ne le termine jamais. J'ai plafonné sa croissance à 256 Mo, en incrémentant de 16 Mo, ce qui explique pourquoi il a échoué, mais en réalité je n'en ai pas besoin pour tout enregistrer. Existe-t-il un moyen de contourner complètement la journalisation sur toute requête exécutée sur la base de données?
Merci pour les réponses à l'avance!
EDIT: Selon les suggestions de @ mattmc3, j'ai implémenté SqlBulkCopy pour toute la procédure. Cela fonctionne AMAZING, sauf que ma boucle est en train de planter sur le tout dernier morceau qui doit être inséré. Je ne sais pas trop où je me trompe, je ne sais même pas si c'est une bonne boucle, alors j'apprécierais de l'aide.
Je sais que c'est un problème avec les derniers appels GetDataTable ou SetSqlBulkCopy. Je suis en train d'insérer des lignes 788189, 788000 entrer et les 189 restants déferlent ...
string[] Rows;
using (StreamReader Reader = new StreamReader("C:/?.csv")) {
Rows = Reader.ReadToEnd().TrimEnd().Split(new char[1] {
'\n'
}, StringSplitOptions.RemoveEmptyEntries);
};
int RowsInserted = 0;
using (SqlConnection Connection = new SqlConnection("")) {
Connection.Open();
DataTable Table = null;
while ((RowsInserted < Rows.Length) && ((Rows.Length - RowsInserted) >= 1000)) {
Table = GetDataTable(Rows.Skip(RowsInserted).Take(1000).ToArray());
SetSqlBulkCopy(Table, Connection);
RowsInserted += 1000;
};
Table = GetDataTable(Rows.Skip(RowsInserted).ToArray());
SetSqlBulkCopy(Table, Connection);
Connection.Close();
};
static DataTable GetDataTable(
string[] Rows) {
using (DataTable Table = new DataTable()) {
Table.Columns.Add(new DataColumn("A"));
Table.Columns.Add(new DataColumn("B"));
Table.Columns.Add(new DataColumn("C"));
Table.Columns.Add(new DataColumn("D"));
for (short a = 0, b = (short)Rows.Length; a < b; a++) {
string[] Columns = Rows[a].Split(new char[1] {
','
}, StringSplitOptions.RemoveEmptyEntries);
DataRow Row = Table.NewRow();
Row["A"] = Columns[0];
Row["B"] = Columns[1];
Row["C"] = Columns[2];
Row["D"] = Columns[3];
Table.Rows.Add(Row);
};
return (Table);
};
}
static void SetSqlBulkCopy(
DataTable Table,
SqlConnection Connection) {
using (SqlBulkCopy SqlBulkCopy = new SqlBulkCopy(Connection)) {
SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("A", "A"));
SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("B", "B"));
SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("C", "C"));
SqlBulkCopy.ColumnMappings.Add(new SqlBulkCopyColumnMapping("D", "D"));
SqlBulkCopy.BatchSize = Table.Rows.Count;
SqlBulkCopy.DestinationTableName = "E";
SqlBulkCopy.WriteToServer(Table);
};
}
EDIT/CODE FINAL: Ainsi, l'application est maintenant terminée et fonctionne incroyable, et très rapide! @ mattmc3, merci pour toute l'aide! Voici le code final pour quiconque peut le trouver utile:
List<string> Rows = new List<string>();
using (StreamReader Reader = new StreamReader(@"?.csv")) {
string Line = string.Empty;
while (!String.IsNullOrWhiteSpace(Line = Reader.ReadLine())) {
Rows.Add(Line);
};
};
if (Rows.Count > 0) {
int RowsInserted = 0;
DataTable Table = new DataTable();
Table.Columns.Add(new DataColumn("Id"));
Table.Columns.Add(new DataColumn("A"));
while ((RowsInserted < Rows.Count) && ((Rows.Count - RowsInserted) >= 1000)) {
Table = GetDataTable(Rows.Skip(RowsInserted).Take(1000).ToList(), Table);
PerformSqlBulkCopy(Table);
RowsInserted += 1000;
Table.Clear();
};
Table = GetDataTable(Rows.Skip(RowsInserted).ToList(), Table);
PerformSqlBulkCopy(Table);
};
static DataTable GetDataTable(
List<string> Rows,
DataTable Table) {
for (short a = 0, b = (short)Rows.Count; a < b; a++) {
string[] Columns = Rows[a].Split(new char[1] {
','
}, StringSplitOptions.RemoveEmptyEntries);
DataRow Row = Table.NewRow();
Row["A"] = "";
Table.Rows.Add(Row);
};
return (Table);
}
static void PerformSqlBulkCopy(
DataTable Table) {
using (SqlBulkCopy SqlBulkCopy = new SqlBulkCopy(@"", SqlBulkCopyOptions.TableLock)) {
SqlBulkCopy.BatchSize = Table.Rows.Count;
SqlBulkCopy.DestinationTableName = "";
SqlBulkCopy.WriteToServer(Table);
};
}
Quelques suggestions si vous voulez accélérer encore plus. 1.) Au lieu de faire Reader.ReadToEnd(), faites une boucle et faites Reader.ReadLine() une ligne à la fois. Ça prendra moins de mémoire. 2.) Si personne n'accède à votre table pendant le chargement, utilisez l'option 'SqlBulkCopyOptions.TableLock'. 3.Pour vous sauver du code, l'objet SqlBulkCopy infère vos mappages de colonnes si vous nommez les colonnes de la même manière que dans votre table de destination et puisque vous gérez vous-même le découpage, il n'y a aucune raison de définir le .BatchSize non plus. Codage heureux! – mattmc3
Au sujet de la déduction des colonnes, cela fonctionnera-t-il si: 'DBTable = {Id (PK, IDENTITÉ), A, B, C, D}', mais 'DataTable = {A, B, C, D}'? Je pense que ça me donnait des ennuis, c'est pour ça que je les ai spécifiés, mais là encore, j'aurais pu me tromper ... – Gup3rSuR4c
Eh bien, c'est fait! J'ai mis en œuvre tout ce que vous avez recommandé et cela fonctionne incroyable! La mémoire a été réduite de moitié à ~ 85 Mo et l'ensemble de l'opération prend environ 45 secondes à compléter. Et j'ai compris la chose des colonnes ci-dessus, j'avais raison, mais j'ai juste ajouté un espace réservé pour le 'Id 'et cela a fonctionné. 'MERCI DE M'AIDER SUR CELA ET DE M'INSCRIVIR SUR DES CHOSES QUE JE NE SAIS JAMAIS !!!' – Gup3rSuR4c