douchuifk90315 2013-10-16 08:41
浏览 163

在Go中的MySQL中插入行非常慢?

So I have been rewriting an old PHP system to Go looking for some performance gains but I'm not get any. And the problem seems to be in the Inserts i'm doing into Mysql.

So where PHP does some processing of a CSV file, does some hashing and inserts around 10k rows in MySQL it takes 40 seconds (unoptimized code).

Now Go on the other hand stripped away of any processing and just the same inserting of 10k(empty) rows takes 110 seconds.

Both tests are run on the same machine and I'm using the go-mysql-driver.

Now for some Go code:

This is extremely dumbed down code and this still takes almost 2 minutes, compared to PHP which does it in less then half.

db := GetDbCon()
defer db.Close()

stmt, _ := db.Prepare("INSERT INTO ticket ( event_id, entry_id, column_headers, column_data, hash, salt ) VALUES ( ?, ?, ?, ?, ?, ? )")

for i := 0; i < 10000; i++{
    //CreateTicket(columns, line, storedEvent)
    StoreTicket(models.Ticket{int64(0), storedEvent.Id, int64(i),
                    "", "", "", "", int64(0), int64(0)}, *stmt)
}

//Extra functions
func StoreTicket(ticket models.Ticket, stmt sql.Stmt){
    stmt.Exec(ticket.EventId, ticket.EntryId, ticket.ColumnHeaders, ticket.ColumnData, ticket.Hash, ticket.Salt)
}

func GetDbCon() (sql.DB) {
    db, _ := sql.Open("mysql", "bla:bla@/bla")

    return *db
}

Profiler result

So is it my code, the go-mysql-driver or is this normal and is PHP just really fast in inserting records?

==EDIT==

As per requested, I have recorded both PHP and Go runs with tcpdump: The files:

I have a hard time reaching any conclusions comparing the two logs, both seem to be sending the same size packets back and forth. But with Go(~110) mysql seems to almost take twice as long to process the request then with PHP(~44), also Go seems to wait slightly longer before sending a new request again(the difference is minimal though).

  • 写回答

2条回答 默认 最新

  • duanji5116 2014-01-27 17:01
    关注

    It's an old question but still - better late than never; you're in for a treat:

    put all your data into a bytes.Buffer as tab-separated, newline terminated and unquoted lines (if the text causes problems, it has to be escaped first). NULL has to be encoded as \N.

    Use http://godoc.org/github.com/go-sql-driver/mysql#RegisterReaderHandler and register a function returning that buffer under "instream". Next, call LOAD DATA LOCAL INFILE "Reader::instream" INTO TABLE ... - that's a very fast way to pump data into MySQL (I measured about 19 MB/sec with Go from a file piped from stdin compared to 18 MB/sec for the MySQL command line client when uploading data from stdin).

    As far as I know, that very driver is the only way to LOAD DATA LOCAL INFILE without the need of a file.

    评论

报告相同问题?

悬赏问题

  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法