Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 不带datatable的SqlBulkCopy列表_C#_.net_Multithreading_Sqlbulkcopy - Fatal编程技术网

C# 不带datatable的SqlBulkCopy列表

C# 不带datatable的SqlBulkCopy列表,c#,.net,multithreading,sqlbulkcopy,C#,.net,Multithreading,Sqlbulkcopy,我们有一个大约100000条记录的大列表,希望将其插入到sql表中 我们正在做的是;将该列表转换为数据表并将数据表传递给SqlBulkcopy方法 从列表到数据表的转换需要更多的时间。尝试使用并行,但由于Datatable不是线程安全的,因此避免了 添加生成整数列表并将其插入临时表的示例poc代码 static void Main(string[] args) { List<int> valueList = GenerateList(100000);

我们有一个大约100000条记录的大列表,希望将其插入到sql表中

我们正在做的是;将该列表转换为数据表并将数据表传递给SqlBulkcopy方法

从列表到数据表的转换需要更多的时间。尝试使用并行,但由于Datatable不是线程安全的,因此避免了

添加生成整数列表并将其插入临时表的示例poc代码

static void Main(string[] args)
    {
        List<int> valueList = GenerateList(100000);

        Console.WriteLine("Starting with Bulk Insert ");

         DateTime startTime = DateTime.Now;
        int recordCount = BulkInsert(valueList);

        TimeSpan ts = DateTime.Now.Subtract(startTime);

        Console.WriteLine("Bulk insert for {0} records in {1} miliseconds.-> ", recordCount, ts.Milliseconds);

        Console.WriteLine("Done.");
        Console.ReadLine();

    }

    private static int BulkInsert(List<int> valueList)
    {
        SqlBulkHelper sqlBulkHelper = new SqlBulkHelper();

        var eventIdDataTable = CreateIdentityDataTable(valueList, "SqlTable", "Id");
        return FillBulkPoundTable(eventIdDataTable, "#SqlTable");
    }

    private static List<int> GenerateList(int size)
    {
        return Enumerable.Range(0, size).ToList();
    }

    private static DataTable CreateIdentityDataTable(List<int> ids, string dataTableName, string propertyName)
    {
        if (ids == null) return null;

        using (var dataTable = new DataTable(dataTableName))
        {
            dataTable.Locale = CultureInfo.CurrentCulture;
            var dtColumn = new DataColumn(propertyName, Type.GetType("System.Int32"));
            dataTable.Columns.Add(dtColumn);

            foreach (int id in ids)
            {
                DataRow row = dataTable.NewRow();
                row[propertyName] = id;
                dataTable.Rows.Add(row);
            }
            return dataTable;
        }
    }

    private static int FillBulkPoundTable(DataTable dataTable, string destinationTableName)
    {
        int totalInsertedRecordCount = 0;
        using (SqlConnection _connection = new SqlConnection(CongifUtil.sqlConnString))
        {
            string sql =
                 @"If object_Id('tempdb..#EventIds') is not null drop table #EventIds
                  CREATE TABLE #EventIds(EvId int) ";


            _connection.Open();
            using (var command = new SqlCommand(sql, _connection))
            {
                command.ExecuteNonQuery();
            }

            using (var sqlBulkCopy = new SqlBulkCopy(_connection))
            {
                sqlBulkCopy.BulkCopyTimeout = 0;
                sqlBulkCopy.DestinationTableName = destinationTableName;
                sqlBulkCopy.WriteToServer(dataTable);
            }

            using (var command = new SqlCommand(sql, _connection))
            {
                command.CommandText = "Select Count(1) as RecordCount from #EventIds";
                SqlDataReader reader = command.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {

                        totalInsertedRecordCount = Convert.ToInt32(reader["RecordCount"]);

                    }
                }
            }
        }
        return totalInsertedRecordCount;
    }
目前需要8秒左右的时间,但我们需要加快速度。原因是我们的目标是插入900000条记录,每个记录将分为100000批

你能给我们一些提示,我们怎样才能使它更完美、更快


另外,也尝试过使用Dapper insert,但它并不比BulkCopy快。

首先将列表转换为XML,例如

List<int> Branches = new List<int>();
Branches.Add(1);
Branches.Add(2);
Branches.Add(3);

XElement xmlElements = new XElement("Branches", Branches.Select(i => new 
XElement("branch", i)));
然后将xml作为参数传递给SP,并将其直接插入到表中,例如:

 DECLARE @XML XML
 SET @XML = '<Branches>
<branch>1</branch>
<branch>2</branch>
<branch>3</branch>
</Branches>'

DECLARE @handle INT  
DECLARE @PrepareXmlStatus INT  

EXEC @PrepareXmlStatus= sp_xml_preparedocument @handle OUTPUT, @XML  

SELECT  * FROM    OPENXML(@handle, '/Branches/branch', 2)  
WITH (
branch varchar
)  

EXEC sp_xml_removedocument @handle 
巴赫尺寸 据我所知,您尝试以100000的批大小插入。高并不总是好的

尝试将该值降低到5000,并检查性能差异

您增加了数据库往返的数量,但由于此处涉及的行大小等因素太多,也可能会加快速度

台锁 使用SqlBulkCopyOptions.TableLock将提高插入性能

using (var sqlBulkCopy = new SqlBulkCopy(_connection, SqlBulkCopyOptions.KeepIdentity))

因此,在没有看到代码的情况下,您希望我们建议将其完善并更快吗?对于初学者来说,如果你能说明你希望它更加完美,那会有帮助吗?30%还是70%?我们做的不超过90%。还要快多少?10分钟以内行吗?如果您能展示需要完美和快速的代码,我们的任务会更容易一些,但我不妨告诉您,代码审查问题在这里有点离题,可能会在codereview.se上出现。这种形式的这个不会。因此,首先要改进它,然后考虑你的选择。使用一个替代DATATATE会省去开销。同意你的观点雷内。添加了示例代码。具体需要8秒的时间?只有sqlBulkCopy.WriteToServer方法还是整个程序?在我看来,只有10万排的座位有点高。嗨,阿比,试过这一排。从xml插入比从BulkCopy插入慢