簡體   English   中英

提高OleDB插入語句的性能,BeginTransaction CommitTransaction

[英]Increase performance on OleDB insert into statement, BeginTransaction CommitTransaction

我編寫了附加函數,將自定義c#列表中的數據插入到MSAccess中。

第一個只為每個單獨的記錄集設置一個新連接:

        public static void appenddatatotable(string connectionstring, string tablename, string[] values)
    {

            var myconn = new OleDbConnection(connectionstring);


            var cmd = new OleDbCommand();
            cmd.CommandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";

            cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", values[0]), new OleDbParameter("@ReportingGroup", values[1]), new OleDbParameter("@Tariff", values[2]), new OleDbParameter("@Year", values[3])});
            cmd.Connection = myconn;
            myconn.Open();
            cmd.ExecuteNonQuery();
            myconn.Close();

    }

然后我簡單地遍歷我的值列表並在每次迭代時調用此函數。 這很好但很慢。

在第二個函數中,我嘗試在函數中包含循環,並使用BeginTransction和Committransaction:

        public static void appenddatatotable2(string connectionstring, string tablename, string datstr, List<PowRes> values)
    {

        var myconn = new OleDbConnection(connectionstring);
        int icounter = 0;

        var cmd = new OleDbCommand();
        OleDbTransaction trans = null;

        cmd.Connection = myconn;
        myconn.Open();
        foreach (var item in values)
        {
            if (icounter == 0)
            {
                trans = cmd.Connection.BeginTransaction();
                cmd.Transaction = trans;
            }

            cmd.CommandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";
            if (string.IsNullOrEmpty(item.yr))
                item.yr = "";

            cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", datstr), new OleDbParameter("@ReportingGroup", item.RG), new OleDbParameter("@Tariff", item.tar), new OleDbParameter("@Year", item.yr)});
            cmd.ExecuteNonQuery();
            icounter++;
            if (icounter >= 500)
            {
                trans.Commit();
                icounter = 0;
            }
        }
        if (icounter > 0)
        {
            trans.Commit();
        }


        myconn.Close();

    }

這也可以正常工作但速度慢。

我的代碼錯了嗎? 我怎么能加快多個插入?

謝謝!

沒有測試,只是我對你的第二個函數的猜測:你在循環中向同一個命令添加太多參數 - cmd.Parameters在每次使用之前從未被清除過..

通常在一個連接中提交大量命令比在單個連接中逐個提交命令要快得多。

另一種加速插入的方法是將所有插入語句轉儲為長文本,用分號分隔,然后一次性觸發提交(我不確定msAccess是否支持它)

編輯:

將update命令合並到一個文本中:

var updates = values.Select(x => string.Format("INSERT INTO myTable ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES({0}, {1}, {2}, {3})",
                datstr, x.RG, x.tar, x.yr))
                .Aggregate((m, n) => m + ";" + n);
cmd.CommandText = update;

雖然這可能有SQL注入問題。

這應該比所有現有版本快得多

public static void appenddatatotable2(string connectionstring, string tablename, string datstr, List<PowRes> values)
        {
            string commandText = "INSERT INTO " + tablename + " ([RunDate],[ReportingGroup], [Tariff], [Year]) VALUES(@RunDate, @ReportingGroup, @Tariff, @Year)";
            using (var myconn = new OleDbConnection(connectionstring))
            {
                myconn.Open();
                using (var cmd = new OleDbCommand())
                {
                    foreach (var item in values)
                    {
                        cmd.CommandText = commandText;
                        cmd.Parameters.Clear();
                        cmd.Parameters.AddRange(new[] { new OleDbParameter("@RunDate", datstr), new OleDbParameter("@ReportingGroup", item.RG), new OleDbParameter("@Tariff", item.tar), new OleDbParameter("@Year", item.yr) });
                        cmd.Connection = myconn;
                        cmd.Prepare(); 
                        cmd.ExecuteNonQuery();
                    }
                }   
            }
        }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM