mysql批量插入事务无法正常工作

gdx19jrr  于 2021-07-26  发布在  Java
关注(0)|答案(0)|浏览(387)

更新:我之所以使用代码从另一台服务器写入mysql服务器,是因为这是一个实验。我需要记录插入所有这些行所需的时间。通过其他方法将数据本地加载到mysql并不是问题所在。
我试图在另一台服务器上的mysql数据库中插入超过1500万行的记录。我使用了“github.com/go-sql-driver/mysql”驱动程序和事务。然而,我花了大约75分钟完成插入。两台服务器之间的带宽超过1gb/s。mysql的cpu和内存利用率始终低于20%,只有1核cpu和2gb内存。代码段如下:

  1. fmt.Println("Connecting to MySQL...")
  2. db, err := sql.Open("mysql", "root:password@tcp(ipAddress:3306)/ssc")
  3. if err != nil {
  4. panic(err.Error())
  5. }
  6. fmt.Println("Connected to MySQL")
  7. defer db.Close()
  8. var transaction *sql.Tx
  9. var stmt *sql.Stmt
  10. transaction, err = db.Begin()
  11. stmt, err = transaction.Prepare(`INSERT INTO Star2002PrimaryTracks(primaryTracks, offsetInByte, sizeInByte) VALUE (?, ?, ?)`)
  12. start := time.Now()
  13. // primaryTracksSlice has over 10 million elements.
  14. for i, ele := range primaryTracksSlice {
  15. if i != 0 && i%100000 == 0 {
  16. // commit transaction. init transaction and stmt
  17. elapsed := time.Since(start)
  18. fmt.Printf("time since:%s\n", elapsed)
  19. transaction.Commit()
  20. fmt.Println("transaction commited with 100000 rows each.")
  21. elapsed = time.Since(start)
  22. fmt.Printf("transaction commited. time since: %s\n", elapsed)
  23. elapsed = time.Since(start)
  24. fmt.Printf("time since:%s\n", elapsed)
  25. transaction, err = db.Begin()
  26. stmt, err = transaction.Prepare(`INSERT INTO Star2002PrimaryTracks(primaryTracks, offsetInByte, sizeInByte) VALUE (?, ?, ?)`)
  27. elapsed = time.Since(start)
  28. fmt.Printf("transaction and stmt initialization. time since: %s\n", elapsed)
  29. } else {
  30. // stmt.exec
  31. stmt.Exec(ele.PrimaryTracks, ele.Offset, ele.Size)
  32. }
  33. }
  34. transaction.Commit()

}
transaction.commit()、db.begin()和transaction.prepare()的完成时间不到一秒。似乎100000 stmt.exec()需要大约30秒才能完成。我认为在transaction.commit()之前,stmt.exec()与将数据传输到mysql服务器没有任何关系,所以不应该花那么长时间。我想问问你们,有什么问题吗?
我觉得我应该更新一下。创建表时使用:

  1. CREATE TABLE `Star2002PrimaryTracks` (`id` INT UNSIGNED AUTO_INCREMENT, `primaryTracks` int, `offsetInByte` int, `sizeInByte` int, primary key (`id`))ENGINE=InnoDB DEFAULT CHARSET=utf8;

没有添加可能是原因的附加索引。只有主键。
我认为stmt.exec()有问题。当它不必将数据提交到mysql服务器时,为什么要花这么长时间执行呢。transaction.commit()不是一个应该完成向mysql服务器提交数据的方法,并且需要相对较长的时间来完成吗?

  1. CREATE TABLE `Star2002PrimaryTracks` (
  2. `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3. `primaryTracks` int(11) DEFAULT NULL,
  4. `offsetInByte` int(11) DEFAULT NULL,
  5. `sizeInByte` int(11) DEFAULT NULL,
  6. PRIMARY KEY (`id`)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=1067367 DEFAULT CHARSET=utf8 |

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题