Utilice el tipo de tabla definida por el usuario de la base de datos MSSQL para realizar la optimización de inserción, inserte 10w de datos en 2 segundos

El texto original proviene de
https://www.cnblogs.com/knowledgesea/p/6232461.html

Hay dos métodos de inserción más rápidos: el
primero es un tipo de tabla personalizada que inserta 10w en 2 segundos, y el
segundo conjunto de datos BULK INSERT común está optimizado para insertar 10w en 1 segundo.

Echemos un vistazo al método de optimización del tipo de tabla personalizada.
Después de SQL Server 2012, se pueden insertar 10w piezas de datos en menos de 2 segundos.

Primero cree un nuevo tipo en la base de datos.

CREATE TYPE CustomerFeedbackTemp AS  TABLE(
BusType int NOT NULL,
CustomerPhone varchar(40) NOT NULL,
BackType int NOT NULL,
Content nvarchar(1000) NOT NULL
)
public void ThirdWay()
        {
    
    
            Stopwatch sw = new Stopwatch();
            Stopwatch sw1 = new Stopwatch();
            DataTable dt = GetTable();
            using (var conn = new SqlConnection(ConnStr))
            {
    
    
                string sql = @"INSERT INTO[dbo].[CustomerFeedback]
                                           ([BusType]
                                           ,[CustomerPhone]
                                           ,[BackType]
                                           ,[Content]
                                          ) select BusType,CustomerPhone,BackType,[Content] from @TempTb";
                using (SqlCommand cmd = new SqlCommand(sql, conn))
                {
    
    
                    cmd.CommandTimeout = 0;
                    SqlParameter catParam = cmd.Parameters.AddWithValue("@TempTb", dt);
                    catParam.SqlDbType = SqlDbType.Structured;
                    catParam.TypeName = "dbo.CustomerFeedbackTemp";
                    conn.Open();
                    Console.WriteLine("从:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "开始循环插入内存表中:" + cnt + "条数据 ...");
                    sw.Start();
                    for (int i = 0; i < cnt; i++)
                    {
    
    
                        DataRow dr = dt.NewRow();
                        dr[0] = m.BusType;
                        dr[1] = m.CustomerPhone;
                        dr[2] = m.BackType;
                        dr[3] = m.Content;
                        dt.Rows.Add(dr);
                    }
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "时,循环插入内存表:" + cnt + "条数据完成 ! 耗时:" + sw.ElapsedMilliseconds + "毫秒。");
                    sw1.Start();
                    if (dt != null && dt.Rows.Count != 0)
                    {
    
    
                        cmd.ExecuteNonQuery();
                        sw.Stop();
                    }
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "时,执行:" + cnt + "条数据的datatable的数据进数据库 ! 耗时:" + sw1.ElapsedMilliseconds + "毫秒。");
                }
            }
        }

En primer lugar, el tipo debería ser fácil de entender para todos, como int, varchar, bit, etc. ¿son todos tipos, entonces este tipo de tabla es un hilo?

De hecho, significa que los usuarios pueden definir una estructura de tabla por sí mismos y tratarlo como un tipo.

Documentación detallada para crear tipos personalizados: https://msdn.microsoft.com/zh-cn/library/ms175007.aspx

En segundo lugar, los tipos personalizados también tienen algunas restricciones, seguridad: https://msdn.microsoft.com/zh-cn/library/bb522526.aspx

Entonces es cómo usar este tipo, su uso se usa como un parámetro con valores de tabla.

Mediante el uso de parámetros con valores de tabla, puede enviar varias filas de datos a instrucciones o rutinas Transact-SQL (como funciones o procedimientos almacenados) sin crear tablas temporales o muchos parámetros.

Los parámetros con valores de tabla son similares a las matrices de parámetros en OLE DB y ODBC, pero tienen una mayor flexibilidad y están más estrechamente integrados con Transact-SQL. Otra ventaja de los parámetros con valores de tabla es la capacidad de participar en operaciones basadas en conjuntos de datos.

Transact-SQL pasa parámetros con valores de tabla a la rutina por referencia para evitar crear una copia de los datos de entrada. Puede usar parámetros con valores de tabla para crear y ejecutar rutinas Transact-SQL, y puede usar cualquier lenguaje administrado para llamarlos desde código Transact-SQL, clientes administrados y clientes nativos.

ventaja

Al igual que otros parámetros, el alcance de los parámetros con valores de tabla también es un procedimiento almacenado, una función o un texto Transact-SQL dinámico. De manera similar, las variables de tipo de tabla tienen el mismo alcance que cualquier otra variable local creada con la instrucción DECLARE. Puede declarar variables con valores de tabla dentro de declaraciones dinámicas de Transact-SQL y puede pasar estas variables como parámetros con valores de tabla a funciones y procedimientos almacenados.

Los parámetros con valores de tabla tienen una mayor flexibilidad. En algunos casos, pueden proporcionar un mejor rendimiento que las tablas temporales u otros métodos para pasar listas de parámetros. Los parámetros con valores de tabla tienen las siguientes ventajas:

Al completar los datos del cliente por primera vez, no se adquiere ningún bloqueo.

Proporcione un modelo de programación simple.

Permita que la lógica empresarial compleja se incluya en una sola rutina.

Reducir los viajes de ida y vuelta al servidor.

Puede tener estructuras de mesa con diferente cardinalidad.

Está fuertemente tipado.

Permita que el cliente especifique el orden de clasificación y la clave única.

Cuando se utiliza en un procedimiento almacenado, se almacena en caché como una tabla temporal. A partir de SQL Server 2012, para las consultas con parámetros, los parámetros con valores de tabla también se almacenan en caché.

límite

Los parámetros con valores de tabla tienen las siguientes restricciones:

SQL Server no mantiene estadísticas para columnas de parámetros con valores de tabla.

Los parámetros con valores de tabla deben pasarse a las rutinas Transact-SQL como parámetros de entrada READONLY. No puede realizar operaciones DML como UPDATE, DELETE o INSERT en los parámetros con valores de tabla en el cuerpo de la rutina.

No puede utilizar parámetros con valores de tabla como destino de una instrucción SELECT INTO o INSERT EXEC. Los parámetros con valores de tabla pueden estar en la cláusula FROM de SELECT INTO o en cadenas INSERT EXEC o procedimientos almacenados.

Optimización de inserción de conjuntos de datos BULK INSERT comunes

public void FourWay()
        {
    
    

            Stopwatch sw = new Stopwatch();
            Stopwatch sw1 = new Stopwatch();
            DataTable dt = GetTable();
            using (SqlConnection conn = new SqlConnection(ConnStr))
            {
    
    
                SqlBulkCopy bulkCopy = new SqlBulkCopy(conn);
                bulkCopy.BulkCopyTimeout = 0;
                bulkCopy.DestinationTableName = "CustomerFeedback";
                bulkCopy.BatchSize = dt.Rows.Count;
                conn.Open();
                Console.WriteLine("从:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "开始循环插入内存表中:" + cnt + "条数据 ...");
                sw.Start();
                for (int i = 0; i < cnt; i++)
                {
    
    
                    DataRow dr = dt.NewRow();
                    dr[0] = m.BusType;
                    dr[1] = m.CustomerPhone;
                    dr[2] = m.BackType;
                    dr[3] = m.Content;
                    dt.Rows.Add(dr);
                }
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "时,循环插入内存表:" + cnt + "条数据完成 ! 耗时:" + sw.ElapsedMilliseconds + "毫秒。");
                sw1.Start();
                if (dt != null && dt.Rows.Count != 0)
                {
    
    
                    bulkCopy.WriteToServer(dt);
                    sw.Stop();
                }
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss fff") + "时,执行:" + cnt + "条数据的datatable的数据进数据库 ! 耗时:" + sw1.ElapsedMilliseconds + "毫秒。");
            }

Supongo que te gusta

Origin blog.csdn.net/phker/article/details/103124792
Recomendado
Clasificación