Délai d'attente expiré à l'aide de SqlBulkCopy lorsqu'il y a 300 millions de lignes dans la base de données SQL Server

sql sqlbulkcopy timeout

Question

Je n'éprouvais aucun problème à insérer environ 15 000 lignes dans la base de données SQL Server lors de l'utilisation de SQLBulkCopy dans certaines conditions où la base contenait 183 millions de lignes.

Mais quand il y avait 300 millions de lignes existantes dans la base de données, j'ai rencontré l'exception:

Le délai d'attente a expiré. Le délai d'attente écoulé avant la fin de l'opération ou le serveur ne répond pas.

Notez qu'il n'y a pas de contrainte ou quoi que ce soit. C'est juste une table dénormalisée.

using (var sqlBulkCopy = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.TableLock, null))
            {
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_HISTORY_PARMETER_ID,
                    SqlServerDatabaseStrings.SQL_FIELD_HISTORY_PARMETER_ID);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_SOURCE_TIMESTAMP,
                    SqlServerDatabaseStrings.SQL_FIELD_SOURCE_TIMESTAMP);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_VALUE_STATUS,
                    SqlServerDatabaseStrings.SQL_FIELD_VALUE_STATUS);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_ARCHIVE_STATUS,
                    SqlServerDatabaseStrings.SQL_FIELD_ARCHIVE_STATUS);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_INTEGER_VALUE,
                    SqlServerDatabaseStrings.SQL_FIELD_INTEGER_VALUE);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_DOUBLE_VALUE,
                    SqlServerDatabaseStrings.SQL_FIELD_DOUBLE_VALUE);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_STRING_VALUE,
                    SqlServerDatabaseStrings.SQL_FIELD_STRING_VALUE);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_ENUM_NAMEDSET_NAME,
                    SqlServerDatabaseStrings.SQL_FIELD_ENUM_NAMEDSET_NAME);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_ENUM_NUMERIC_VALUE,
                    SqlServerDatabaseStrings.SQL_FIELD_ENUM_NUMERIC_VALUE);
                sqlBulkCopy.ColumnMappings.Add(SqlServerDatabaseStrings.SQL_FIELD_ENUM_TEXTUAL_VALUE,
                    SqlServerDatabaseStrings.SQL_FIELD_ENUM_TEXTUAL_VALUE);

                sqlBulkCopy.DestinationTableName =
                    SqlServerDatabaseStrings.SQL_TABLE_HISTORYSAMPLEVALUES;
                sqlBulkCopy.WriteToServer(historySampleValuesDataRow);
                sqlBulkCopy.Close();

            }

Des idées sur ce qui se passe? BTW, SQL Server Standard est ce que j'utilise

Réponse acceptée

Vous avez 2 propriétés sur votre objet sqlBulkCopy qui peuvent vous aider

  • BulkCopyTimeout: Il s'agit de la valeur du délai d'attente, 30 secondes par défaut. Définissez cette valeur sur 0 pour désactiver complètement le délai.
  • BatchSize: au lieu d'insérer 300MM directement dans la table, insère les enregistrements à une taille de lot, peut-être 1MM / heure, pour éviter le problème de délai d'expiration (et faciliter le chargement un peu)

Les références:



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi