• MySql批量插入的性能比较


      为了提高性能,需要对mysql批量插入进行一次性对对比,下面是测试完后的结果,存档以备后查。

    1.    测试结果

    记录条数

    循环插入,一个事务提交insert00(ms)

    批量函数插入

    insert01(ms)

    一个inser多个values

    insert02 (ms)

    多个insert拼接

    insert03(ms)

    4681

    1225

    203

    420

    2566

    100

    34

    5

    5

    51

    500

    131

    22

    18

    231

    1000

    251

    46

    37

    476

    2000

    484

    89

    111

    1047

    4000

    950

    173

    366

    2683

    8000

    2092

    334

    1073

    7684

    15000

    3646

    588

    3283

    16900

    20000

    4716

    780

    6638

     

    30000

    7102

    1146

    10699

     

    注:批量函数的上限是:4681条记录                 

     2.    源码

    package main
    
    import (
      "fmt"
      "strconv"
      "strings"
      "time"
      _ "github.com/go-sql-driver/mysql"
      "github.com/jmoiron/sqlx"
    )
    
    func main() {
      accountings := initData(15000)
      //insert00(accountings)
      //insert01(accountings)
      //insert02(accountings)
      insert03(accountings)
    }
    func initData(length int) []Accounting {
      accountings := make([]Accounting, length)
    
      for i := 0; i < length; i++ {
        ii, _ := strconv.Atoi(time.Now().Format("20060102150405") + fmt.Sprint(i))
        accountings[i] = Accounting{
          No:           uint64(ii),
          AccountNo:    132079455772000256,
          AccountTime:  time.Now(),
          Amount:       1000,
          Balance:      0,
          Currency:     "JPY",
          Direction:    1,
          Operation:    "charge",
          IsDischarge:  false,
          BusinessID:   "b" + fmt.Sprint(i),
          BusinessTime: time.Now(),
          BusinessCode: "StarPay",
          CreateTime:   time.Now(),
          GroupID:      "group000" + fmt.Sprint(i),
        }
      }
      return accountings
    }
    
    func insert00(accountings []Accounting) {
      begin := time.Now()
      insertSQL := `INSERT INTO accounting
      (no,account_no,account_time,amount,balance,currency,direction,operation,is_discharge,business_id,business_time,business_code,create_time,group_id)
      VALUES
      (?,?,?,?,?,?,?,?,?,?,?,?,?,?)`
      db, _ := sqlx.Open("mysql", "root:!Gsw790622@tcp(127.0.0.1:3306)/starpay_acct?charset=utf8")
    
      conn, _ := db.Beginx()
      for _, e := range accountings {
        conn.Exec(insertSQL, e.No, e.AccountNo, e.AccountTime, e.Amount, e.Balance, e.Currency, e.Direction, e.Operation, e.IsDischarge, e.BusinessID, e.BusinessTime, e.BusinessCode, e.CreateTime, e.GroupID)
      }
      conn.Commit()
      fmt.Println(time.Now().Sub(begin).Microseconds())
      defer db.Close()
    }
    
    func insert01(accountings []Accounting) {
      begin := time.Now()
    
      insertSQL := `INSERT INTO accounting
      (no,account_no,account_time,amount,balance,currency,direction,operation,is_discharge,business_id,business_time,business_code,create_time,group_id)
      VALUES
      (:no,:account_no,:account_time,:amount,:balance,:currency,:direction,:operation,:is_discharge,:business_id,:business_time,:business_code,:create_time,:group_id)`
      db, _ := sqlx.Open("mysql", "root:!Gsw790622@tcp(127.0.0.1:3306)/starpay_acct?charset=utf8")
      conn, _ := db.Beginx()
      ind := len(accountings) / 4000
      yu := len(accountings) % 4000
      if yu > 0 {
        ind = ind + 1
      }
      for i := 0; i < ind; i++ {
    
        end := (i + 1) * 4000
        if i == ind-1 && yu != 0 {
          end = (i * 4000) + yu
        }
        accs := accountings[i*4000 : end]
        conn.NamedExec(insertSQL, accs)
    
      }
      conn.Commit()
      fmt.Println(time.Now().Sub(begin).Microseconds())
      defer db.Close()
    }
    
    func insert02(accountings []Accounting) {
      begin := time.Now()
      values := make([]string, len(accountings))
      for i := 0; i < len(values); i++ {
        account := accountings[i]
        value := `(` + fmt.Sprint(account.No) + "," + fmt.Sprint(account.AccountNo) + ",'" + account.AccountTime.Format("2006-01-02 15:04:05.000") + "'," + strconv.FormatFloat(account.Amount, 'f', 4, 64) + "," + strconv.FormatFloat(account.Balance, 'f', 4, 64) + ",'" + account.Currency + "'," + strconv.Itoa(int(account.Direction)) + ",'" + account.Operation + "'," + strconv.FormatBool(account.IsDischarge) + ",'" + account.BusinessID + "','" + account.BusinessTime.Format("2006-01-02 15:04:05.000") + "','" + account.BusinessCode + "','" + account.CreateTime.Format("2006-01-02 15:04:05.000") + "','" + account.GroupID + "')"
        values[i] = value
      }
      insertSQL := `INSERT INTO accounting
      (no,account_no,account_time,amount,balance,currency,direction,operation,is_discharge,business_id,business_time,business_code,create_time,group_id)
      VALUES`
      for i := 0; i < len(values); i++ {
        insertSQL = insertSQL + values[i] + ","
      }
      insertSQL = strings.TrimRight(insertSQL, ",")
      fmt.Println(time.Now().Sub(begin).Microseconds())
      db, _ := sqlx.Open("mysql", "root:!Gsw790622@tcp(127.0.0.1:3306)/starpay_acct?charset=utf8")
      db.Exec(insertSQL)
      fmt.Println(time.Now().Sub(begin).Microseconds())
      defer db.Close()
    }
    func insert03(accountings []Accounting) {
      begin := time.Now()
      insertSQL := `INSERT INTO accounting(no,account_no,account_time,amount,balance,currency,direction,operation,is_discharge,business_id,business_time,business_code,create_time,group_id)  VALUES`
      sumSql := ""
      for i := 0; i < len(accountings); i++ {
        account := accountings[i]
        sumSql = sumSql + insertSQL + `(` + fmt.Sprint(account.No) + "," + fmt.Sprint(account.AccountNo) + ",'" + account.AccountTime.Format("2006-01-02 15:04:05.000") + "'," + strconv.FormatFloat(account.Amount, 'f', 4, 64) + "," + strconv.FormatFloat(account.Balance, 'f', 4, 64) + ",'" + account.Currency + "'," + strconv.Itoa(int(account.Direction)) + ",'" + account.Operation + "'," + strconv.FormatBool(account.IsDischarge) + ",'" + account.BusinessID + "','" + account.BusinessTime.Format("2006-01-02 15:04:05.000") + "','" + account.BusinessCode + "','" + account.CreateTime.Format("2006-01-02 15:04:05.000") + "','" + account.GroupID + "');"
      }
    
      fmt.Println(time.Now().Sub(begin).Microseconds())
      db, _ := sqlx.Open("mysql", "root:!Gsw790622@tcp(127.0.0.1:3306)/starpay_acct?charset=utf8&multiStatements=true")
    
      db.Exec(sumSql)
    
      fmt.Println(time.Now().Sub(begin).Microseconds())
      defer db.Close()
    }
    
    type Accounting struct {
      No                 uint64    `db:"no"`
      AccountNo          uint64    `db:"account_no"`
      AccountTime        time.Time `db:"account_time"`
      Amount             float64   `db:"amount"`
      Balance            float64   `db:"balance"`
      Currency           string    `db:"currency"`
      Direction          int8      `db:"direction"`
      Operation          string    `db:"operation"`
      IsDischarge        bool      `db:"is_discharge"`
      DischaregID        string    `db:"dischareg_id"`
      DischaregAccountNo string    `db:"dischareg_account_no"`
      BusinessID         string    `db:"business_id"`
      BusinessTime       time.Time `db:"business_time"`
      BusinessCode       string    `db:"business_code"`
      CreateTime         time.Time `db:"create_time"`
      GroupID            string    `db:"group_id"`
    }

    3.       监控批量插入函数NamedExec生成的SQL

    2021-06-18T03:21:52.751480Z    12 Execute INSERT INTO accounting

     (no,account_no,account_time,amount,balance,currency,direction,operation,is_discharge,business_id,business_time,business_code,create_time,group_id) VALUES(202106181221520,132079455772000256,'2021-06-1803:21:52.749515',1000,0,'JPY',1,'charge',0,'b0','2021-06-1803:21:52.749515','StarPay','2021-06-1803:21:52.749515','group0000'),(202106181221521,132079455772000256,'2021-06-1803:21:52.749519',1000,0,'JPY',1,'charge',0,'b1','2021-06-1803:21:52.749519','StarPay','2021-06-18 03:21:52.749519','group0001'),(202106181221522,132079455772000256,'2021-06-1803:21:52.749521',1000,0,'JPY',1,'charge',0,'b2','2021-06-1803:21:52.749521','StarPay','2021-06-1803:21:52.749521','group0002'),(202106181221523,132079455772000256,'2021-06-1803:21:52.749522',1000,0,'JPY',1,'charge',0,'b3','2021-06-1803:21:52.749523','StarPay','2021-06-1803:21:52.749523','group0003'),(202106181221524,132079455772000256,'2021-06-1803:21:52.749524',1000,0,'JPY',1,'charge',0,'b4','2021-06-1803:21:52.749524','StarPay','2021-06-18 03:21:52.749524','group0004')

      想要更快更方便的了解相关知识,可以关注微信公众号 
     

     

  • 相关阅读:
    JavaCV入门指南之快速上手篇:快速上手视频拉流、推流、录制文件、录屏、截图和编解码复用解复用等常用音视频处理操作
    javacv开发详解补充篇:如何将rgb/bgr像素数据优雅高效的转换为BufferedImage
    JavaCV开发详解之21:如何使用JavaCV接入gb28181的ps流并推流到流媒体服务和接入海康大华sdk回调h264/hevc裸流
    javacv开发详解补充篇:解决转流后视频画面快进慢放,时间跳动过大,监控视频时间戳重新计算pts和dts
    为啥你写的文章没人看?关于内容创作的两大玄学分析:认真写的没人看,随便写的火的一塌糊涂
    JavaCV进阶opencv图像检测识别:ffmpeg视频图像画面人脸检测
    JavaCV进阶opencv图像检测识别:摄像头图像人脸检测
    「Elasticsearch」ES重建索引怎么才能做到数据无缝迁移呢?
    【手记】让Fiddler捕获到SQLCLR中的网络请求
    .Net程序连接SQL Server默认会话选项备查
  • 原文地址:https://www.cnblogs.com/axzxs2001/p/15872796.html
Copyright © 2020-2023  润新知