Saltar al contenido

Inserte 2 millones de filas en SQL Server rápidamente

Encontramos la contestación a esta obstáculo, o por lo menos eso deseamos. Si presentas inquietudes puedes dejar un comentario, para nosotros será un placer responderte

Solución:

  1. Creo que es mejor que lea los datos del archivo de texto en DataSet

  2. Poner a prueba o probar SqlBulkCopy – Inserción masiva en SQL desde la aplicación C #

    // connect to SQL
    using (SqlConnection connection = new SqlConnection(connString))
    
        // make sure to enable triggers
        // more on triggers in next post
        SqlBulkCopy bulkCopy = new SqlBulkCopy(
            connection, 
            SqlBulkCopyOptions.TableLock 
    // reset
    this.dataTable.Clear();
    

o

después de hacer el paso 1 en la parte superior

  1. Crear XML a partir de DataSet
  2. Pase XML a la base de datos y realice una inserción masiva

Puede consultar este artículo para obtener más detalles: Inserción masiva de datos utilizando C # DataTable y la función OpenXML del servidor SQL

Pero no se ha probado con 2 millones de registros, solo consumirá memoria en la máquina, ya que debe cargar 2 millones de registros e insertarlos.

Puedes probar con SqlBulkCopy clase.

Le permite cargar de manera masiva de manera eficiente una tabla de SQL Server con datos de otra fuente.

Hay una publicación de blog interesante sobre cómo se puede usar.

Re la solución para SqlBulkCopy:

Usé StreamReader para convertir y procesar el archivo de texto. El resultado fue una lista de mi objeto.

Creé una clase que toma Datatable o un List y un tamaño de búfer (CommitBatchSize). Convertirá la lista en una tabla de datos usando una extensión (en la segunda clase).

Funciona muy rapido. En mi PC, puedo insertar más de 10 millones de registros complicados en menos de 10 segundos.

Aquí está la clase:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DAL


public class BulkUploadToSql

    public IList InternalStore  get; set; 
    public string TableName  get; set; 
    public int CommitBatchSize  get; set; =1000;
    public string ConnectionString  get; set; 

    public void Commit()
    
        if (InternalStore.Count>0)
        
            DataTable dt;
            int numberOfPages = (InternalStore.Count / CommitBatchSize)  + (InternalStore.Count % CommitBatchSize == 0 ? 0 : 1);
            for (int pageIndex = 0; pageIndex < numberOfPages; pageIndex++)
                
                    dt= InternalStore.Skip(pageIndex * CommitBatchSize).Take(CommitBatchSize).ToDataTable();
                BulkInsert(dt);
                
         
    

    public void BulkInsert(DataTable dt)
    
        using (SqlConnection connection = new SqlConnection(ConnectionString))
        
                SqlBulkCopyOptions.UseInternalTransaction,
                null
                );

            // set the destination table name
            bulkCopy.DestinationTableName = TableName;
            connection.Open();

            // write the data in the "dataTable"
            bulkCopy.WriteToServer(dt);
            connection.Close();
        
        // reset
        //this.dataTable.Clear();
    



public static class BulkUploadToSqlHelper

    public static DataTable ToDataTable(this IEnumerable data)
    
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        DataTable table = new DataTable();
        foreach (PropertyDescriptor prop in properties)
            table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
        foreach (T item in data)
        
            DataRow row = table.NewRow();
            foreach (PropertyDescriptor prop in properties)
                row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
            table.Rows.Add(row);
        
        return table;
    

Aquí hay un ejemplo cuando quiero insertar una lista de mi objeto personalizado List (ListDetections):

var objBulk = new BulkUploadToSql()

        InternalStore = ListDetections,
        TableName= "PuckDetections",
        CommitBatchSize=1000,
        ConnectionString="ENTER YOU CONNECTION STRING"
;
objBulk.Commit();

los BulkInsert La clase se puede modificar para agregar un mapeo de columnas si es necesario. Ejemplo tienes una identidad key como primera columna (esto asumiendo que los nombres de las columnas en la tabla de datos son los mismos que los de la base de datos)

//ADD COLUMN MAPPING
foreach (DataColumn col in dt.Columns)

        bulkCopy.ColumnMappings.Add(col.ColumnName, col.ColumnName);

Puntuaciones y reseñas

Finalizando este artículo puedes encontrar las notas de otros administradores, tú todavía tienes el poder insertar el tuyo si lo crees conveniente.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *