欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mysql数据插入效率比较

程序员文章站 2022-09-24 16:32:03
做数据插入时,发现之前上班做哪些办公系统压根就没考虑过数据库性能这些,因为涉及的数据量小,时间和效率看不出来,可当数据量很大了,大到了每秒需要10000次插入时,这时就不得...

做数据插入时,发现之前上班做哪些办公系统压根就没考虑过数据库性能这些,因为涉及的数据量小,时间和效率看不出来,可当数据量很大了,大到了每秒需要10000次插入时,这时就不得不考虑你的sql 语句了。当插入100条数据,能想到的数据插入方式:

1:for循环100次,一次次插入数据。连接一次插入100次,这样是最费时间的也是最费io和连接的;

2:将100数据插入语句组成一个sql语句,然后连接一次,插入数据。这种费时比第一种要好。

3:使用事物,100次插入,最后一次事物commit; 这种比第二种更快;

4:使用insert语句本身的多数据插入;

当以上方法在少量的数据面前,几乎没什么差别,我们压根感觉不出来。可是,当数据量稍微提大点,比如一次10000条数据。插入的速度效率就出来;

这是mysql实例类;此实例提供mysql的连接,和数据库相关操作

public class mysqlinstance
  {
    //连接字符串
    private static string mysqlconnectionstr = "server =localhost;database=test;uid=root;pwd=password.1;";
    private static mysqlconnection _mysqlconnect;
    private static mysqlconnection mysqlconnect
    {
      get
      {
        if (null == _mysqlconnect)
        {
          _mysqlconnect = new mysqlconnection(mysqlconnectionstr);
        }
        return _mysqlconnect;
      }
    }
    private static mysqlcommand _mysqlcommand;
    private static mysqlcommand mysqlcommand
    {
      get
      {
        if (null == _mysqlcommand)
        {
          _mysqlcommand = mysqlconnect.createcommand();
        }
        return _mysqlcommand;
      }
    }
    //打开连接
    public static void openconnect()
    {
      mysqlconnect.open();
    }
    //关闭连接
    public static void closeconnect()
    {
      mysqlconnect.close();
    }
    public static mysqlconnection connection
    {
      get
      {
        return mysqlconnect;
      }
    }
    //防注入方式的插入数据
    //使用事务 10000插入,最后才一次事务提交
    public static int insertdata(string command, list<mysqlparameter> params)
    {
      //程序时间监控
      stopwatch sw = new stopwatch();
      //程序计时开始
      sw.start();
      openconnect();
      //事务开始
      mysqltransaction trans = mysqlconnect.begintransaction();
      mysqlcommand.commandtext = command;
      mysqlcommand.parameters.addrange(params.toarray());
      int count = 0;
      for (int i = 0; i < 10000; i++)
      {
        if (mysqlcommand.executenonquery() > 0)
          count++;
      }
      //事务提交
      trans.commit();
      closeconnect();
      mysqlcommand.parameters.clear();
      //计时停止
      sw.stop();
      timespan ts2 = sw.elapsed;
      console.writeline(ts2.totalmilliseconds);
      return count;
    }
    //查询出来的是mysqldatareader 要使用就不能关闭连接
    public static mysqldatareader selectdata(string sql)
    {
      stopwatch sw = new stopwatch();
      sw.start();
      // openconnect();
      mysqlcommand newcommond = new mysqlcommand(sql, mysqlconnect);
      mysqldatareader data = newcommond.executereader();
      // closeconnect();
      sw.stop();
      timespan ts2 = sw.elapsed;
      console.writeline(ts2.totalmilliseconds);
      return data;
    }
    /// <summary>
    /// 查询出来的是数据集合
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static dataset selectdataset(string sql)
    {
      mysqlcommand newcommond = new mysqlcommand(sql, mysqlconnect);
      mysqldataadapter adapter = new mysqldataadapter();
      adapter.selectcommand = newcommond;
      dataset ds = new dataset();
      adapter.fill(ds);
      return ds;
    }
    //不安全插入 有注入
    public static int insertdatasql(string sql)
    {
      // openconnect();
      mysqlcommand.commandtext = sql;
      int count = mysqlcommand.executenonquery();
      // closeconnect();
      return count;
    }
    //安全插入 参数使用@
    //不使用事务 10000次插入
    public static int insertdatanotran(string command, list<mysqlparameter> params)
    {
      stopwatch sw = new stopwatch();
      sw.start();
      openconnect();
      mysqlcommand.commandtext = command;
      mysqlcommand.parameters.addrange(params.toarray());
      int count = 0;
      for (int i = 0; i < 10000; i++)
      {
        if (mysqlcommand.executenonquery() > 0)
          count++;
      }
      closeconnect();
      mysqlcommand.parameters.clear();
      sw.stop();
      timespan ts2 = sw.elapsed;
      console.writeline(ts2.totalmilliseconds);
      return count;
    }
    //一次性拼10000个插入语句一次性提交
    public static void test4()
    {
      stopwatch sw = new stopwatch();
      sw.start();
      mysqlinstance.openconnect();
      mysqltransaction tran = mysqlinstance.connection.begintransaction();
      string command = string.empty;
      for (int i = 0; i < 10000; i++)
      {
        string temp = string.format("insert into test.testtable(pname,pwd) value ('{0}','{1}'); \r\n", "name" + i, "password." + i);
        command += temp;
      }
      mysqlinstance.insertdatasql(command);
      tran.commit();
      mysqlinstance.closeconnect();
      sw.stop();
      timespan ts2 = sw.elapsed;
      console.writeline(ts2.totalmilliseconds);
    }
 }

最后建立控制台程序,分别使用事务提交,不使用事务,和拼接10000条插入在组成事务,这三种方式做一个测试,打印出耗时。结果如图:

mysql数据插入效率比较

可以看到:10000次插入使用事务提交只用时4.7秒,而不使用事务用时311秒,拼装成10000次insert语句的耗时7.3秒。这里面耗时7.3秒的,理论上,在数据库sql执行上也应该和使用事务差不多,这里的耗时主要是用作字符串的拼接上,客户端耗时比较多;

贴上测试程序代码:

using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.threading.tasks;
using mysql.data;
using mysql.web;
using mysql.data.mysqlclient;
using system.diagnostics;
using system.data;
namespace mysqldemo01
{
  class program
  {
    static void main(string[] args)
    {      
      testinsert();
      console.readline();
    }
    //使用安全防注入 参数使用@ ,安全插入。
    public static void testinsert()
    {
      list<mysqlparameter> lmp = new list<mysqlparameter>();
      lmp.add(new mysqlparameter("@pname", "hello2"));
      lmp.add(new mysqlparameter("@pwd", "1232"));
      string command = " insert into test.testtable(pname,pwd) value(@pname,@pwd); ";
      mysqlinstance.insertdata(command, lmp);
      list<mysqlparameter> lmp2 = new list<mysqlparameter>();
      lmp2.add(new mysqlparameter("@pname", "hello2"));
      lmp2.add(new mysqlparameter("@pwd", "1232"));
      mysqlinstance.insertdatanotran(command, lmp2);
      test4();
    }
   }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接