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

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

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

fmt.Println("Connecting to MySQL...")

db, err := sql.Open("mysql", "root:password@tcp(ipAddress:3306)/ssc")
if err != nil {
    panic(err.Error())
}

fmt.Println("Connected to MySQL")

defer db.Close()

var transaction *sql.Tx
var stmt *sql.Stmt
transaction, err = db.Begin()
stmt, err = transaction.Prepare(`INSERT INTO Star2002PrimaryTracks(primaryTracks, offsetInByte, sizeInByte)     VALUE (?, ?, ?)`)
start := time.Now()
// primaryTracksSlice has over 10 million elements.
for i, ele := range primaryTracksSlice {
    if i != 0 && i%100000 == 0 {
        // commit transaction. init transaction and stmt
        elapsed := time.Since(start)
                    fmt.Printf("time since:%s\n", elapsed)
                    transaction.Commit()
                    fmt.Println("transaction commited with 100000 rows each.")
        elapsed = time.Since(start)
        fmt.Printf("transaction commited. time since: %s\n", elapsed)

        elapsed = time.Since(start)
        fmt.Printf("time since:%s\n", elapsed)
        transaction, err = db.Begin()
        stmt, err = transaction.Prepare(`INSERT INTO Star2002PrimaryTracks(primaryTracks, offsetInByte, sizeInByte)         VALUE (?, ?, ?)`)
        elapsed = time.Since(start)
        fmt.Printf("transaction and stmt initialization. time since: %s\n", elapsed)
    } else {
        // stmt.exec
        stmt.Exec(ele.PrimaryTracks, ele.Offset, ele.Size)
    }
}
transaction.Commit()

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

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服务器提交数据的方法,并且需要相对较长的时间来完成吗?

CREATE TABLE `Star2002PrimaryTracks` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `primaryTracks` int(11) DEFAULT NULL,
  `offsetInByte` int(11) DEFAULT NULL,
  `sizeInByte` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1067367 DEFAULT CHARSET=utf8 |

暂无答案!

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

相关问题