sql >> Base de Datos >  >> RDS >> Sqlserver

Parámetro con valor de tabla:envío de datos en pequeños fragmentos

Un ejemplo del uso de IEnumerable SqlDataRecord
Funciona como un lector de datos inverso

Aviso que ordeno. Esto es por el índice agrupado. La fragmentación de los índices matará absolutamente la velocidad de carga. La primera implementación usó Insertar valores (sin ordenar) y en una ejecución de 12 horas, esta versión es literalmente 100 veces más rápida. También deshabilito los índices que no sean PK y los vuelvo a indexar al final de la carga. A la larga, obtengo unas 500 filas / segundo. Su muestra es de 1400 / segundo tan grande. Si empiezas a ver degradación, entonces hay cosas que mirar.

public class DocFTSinXsCollection : List<DocFTSinX>, IEnumerable<SqlDataRecord>
{
    // used by TVP for fast insert
    private int sID;
    private IEnumerable<DocFTSinX> docFTSinXs;
    IEnumerator<SqlDataRecord> IEnumerable<SqlDataRecord>.GetEnumerator()
    {
        //todo fix the order in 3 to sID, wordID1, workID2
        var sdr = new SqlDataRecord(
        new SqlMetaData("wordID1", System.Data.SqlDbType.Int),
        new SqlMetaData("wordID2", System.Data.SqlDbType.Int),
        new SqlMetaData("sID", System.Data.SqlDbType.Int),
        new SqlMetaData("Delta", System.Data.SqlDbType.Int));
        foreach (DocFTSinX oh in docFTSinXs.OrderBy(x => x.Word1).ThenBy(x => x.Word2))
        {
            sdr.SetInt32(0, oh.Word1);
            sdr.SetInt32(1, oh.Word2);
            sdr.SetInt32(2, sID);
            sdr.SetInt32(3, (Int32)oh.Delta);
            yield return sdr;
        }
    }

    public DocFTSinXsCollection(int SID, IEnumerable<DocFTSinX> DocFTSinXs)
    {
        sID = SID;
        docFTSinXs = DocFTSinXs;
        //Debug.WriteLine("DocFTSinXsCollection DocFTSinXs " + DocFTSinXs.Count().ToString());
    }
}

Otras herramientas a considerar son la clase SQLBulkCopy .NET y Drapper.

OP preguntó cómo actuar en lotes.

 while (true)
 {
     // if no more break;
     // fill list or datatable with next 100000
     // send list or datatable to db
 }