MySQL 批量 insert 的效率比较代码

代码使用的 C#6.0 语法,需要在 Visual Studio 2015 编译

表结构

CREATE TABLE IF NOT EXISTS `name_value` (
  `int` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT '0',
  `value` varchar(50) NOT NULL DEFAULT '0',
  PRIMARY KEY (`int`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

试验代码

using System;
using System.Text;
using MySql.Data.MySqlClient;

namespace MySql.BatchInsert.Trial
{
    class Program
    {
        const int total = 1000;

        static void Test1(MySqlConnection conn)
        {
            var start = DateTime.Now;

            using (MySqlCommand cmd = new MySqlCommand())
            {
                cmd.Connection = conn;
                cmd.CommandText = @"
insert into name_value
(name, value)
values
(@name, value)";

                var paramName = cmd.CreateParameter();
                paramName.ParameterName = "name";
                var paramValue = cmd.CreateParameter();
                paramValue.ParameterName = "value";

                cmd.Parameters.Add(paramName);
                cmd.Parameters.Add(paramValue);

                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        cmd.Transaction = trans;
                        for (var i = 0; i < total; i++)
                        {
                            paramName.Value = $"name_{i}";
                            paramValue.Value = $"value_{i}";
                            cmd.ExecuteNonQuery();
                        }
                        trans.Commit();
                    }
                    catch (Exception e)
                    {
                        trans.Rollback();
                        Console.WriteLine($"Error: {e}");
                    }
                }
            }

            var end = DateTime.Now;
            Console.WriteLine((end - start).TotalMilliseconds);
        }

        static void Test2(MySqlConnection conn)
        {
            var start = DateTime.Now;

            StringBuilder builder = new StringBuilder(@"
insert into name_value
(name, value)
values");

            using (var cmd = new MySqlCommand())
            {
                cmd.Connection = conn;
                for (var i = 0; i < total; i++)
                {
                    builder.Append($@"
(@name_{i}, @value_{i}),");
                    var paramName = cmd.CreateParameter();
                    paramName.ParameterName = $"name_{i}";
                    var paramValue = cmd.CreateParameter();
                    paramValue.ParameterName = $"value_{i}";

                    cmd.Parameters.Add(paramName);
                    cmd.Parameters.Add(paramValue);

                    paramName.Value = $"name_{i}";
                    paramValue.Value = $"value_{i}";
                }
                builder.Remove(builder.Length - 1, 1);
                cmd.CommandText = builder.ToString();

                using (var trans = conn.BeginTransaction())
                {
                    try
                    {
                        cmd.Transaction = trans;
                        cmd.ExecuteNonQuery();
                        trans.Commit();
                    }
                    catch (Exception e)
                    {
                        trans.Rollback();
                        Console.WriteLine($"Error: {e}");
                    }
                }
            }

            var end = DateTime.Now;
            Console.WriteLine((end - start).TotalMilliseconds);
        }

        static void Main(string[] args)
        {
            MySqlConnectionStringBuilder builder = new MySqlConnectionStringBuilder {
                Server = "dev.kiloway.com.cn",
                Port = 13366,
                UserID = "james",
                Password = "notjustforgaming",
                Database = "test"
            };

            using (MySqlConnection conn = new MySqlConnection(builder.ToString()))
            {
                conn.Open();
                Test2(conn);
                Test1(conn);
            }
        }
    }
}

参考结果(1000条数据)

结果1:

Test1: 14617.2076 (ms)
Test2: 591.4603 (ms)

结果2:

Test1: 14438.1418 (ms)
Test2: 600.0803 (ms)

注意

使用 Test2 中的方法时需要需要考虑每批大小

    原文作者:边城
    原文地址: https://segmentfault.com/a/1190000003068324
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞