更新:我之所以使用代码从另一台服务器写入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 |
暂无答案!
目前还没有任何答案,快来回答吧!