为了账号安全,请及时绑定邮箱和手机立即绑定

批量 MySQL 插入比 PHP 慢 2 倍

批量 MySQL 插入比 PHP 慢 2 倍

Go
猛跑小猪 2023-05-08 16:01:28
我一直在测试 Go,希望将它用于新站点,并希望确保它与 PHP 一样快或更快。所以我运行了一个基本测试,在 Go 和 PHP 中进行批量插入,因为我需要批量插入。我的测试使用事务、准备好的语句、同一台机器、完全相同的表定义、没有索引但 PK 以及函数中的相同逻辑。结果:PHP (mysqli) 中的 100k 插入是 4.42 秒Go(Go-MySQL-Driver)中的 100k 插入是 9.2 秒我正在使用的 go mysql 驱动程序是在这里找到的最受欢迎的“Go-MySQL-Driver”:https: //github.com/go-sql-driver/mysql我想知道是否有人可以告诉我我在 go 中的代码是否设置不正确,或者 go 是否就是这样。这些函数为一些行变量添加了一些可变性,因此每一行都不相同。去功能:func fill_table(w http.ResponseWriter, r *http.Request, result_string *string, num_entries_to_add int) {    defer recover_show_error(result_string)    db := getDBConn()    defer db.Close()    var int_a int = 9      var int_b int = 4      var int_01 int = 1               var int_02 int = 1451628000 // Date Entered  (2016-1-1, 1am)    var int_03 int = 11             var int_04 int = 0    var int_05 int = 0    var float_01 float32 = 90.0 // Value    var float_02 float32 = 0    var float_03 float32 = 0    var text_01 string = ""     var text_02 string = ""    var text_03 string = ""    start_time := time.Now()    tx, err := db.Begin()    if err != nil {        panic(err)    }    stmt, err := tx.Prepare("INSERT INTO " + TABLE_NAME +        "(`int_a`,`int_b`,`int_01`,`int_02`,`int_03`,`int_04`,`int_05`,`float_01`,`float_02`,`float_03`,`text_01`,`text_02`,`text_03`) " +        "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)")    if err != nil {        panic(err)    }    defer stmt.Close()    var flip int = 0    for i := 0; i < num_entries_to_add; i++ {        flip = ((int)(i / 500)) % 2        if flip == 0 {            float_01 += .1 // add to Value        } else {            float_01 -= .1 // sub from Value        }        int_02 += 1 // add a second to date.        _, err = stmt.Exec(int_a, int_b, int_01, int_02, int_03, int_04, int_05, float_01, float_02, float_03, text_01, text_02, text_03)        if err != nil {            panic(err)        }    }    err = tx.Commit()    if err != nil {        panic(err)    }    elapsed := time.Since(start_time)    *result_string += fmt.Sprintf("Fill Table Time = %s</br>\n", elapsed)}
查看完整描述

1 回答

?
翻过高山走不出你

TA贡献1875条经验 获得超3个赞

在我为寻找我想为我的新网站使用哪种语言而进行的测试中,我尝试了 php、golang 和 java。我对任何一种语言都没有太多经验,所以我在这里所说的任何内容都可能在将来被某人纠正。

我的主要测试是批量插入到 mysql 数据库中,因为我的应用程序需要它。

我想远离 php,因为它是一种非编译的旧脚本语言,在很多方面都比 golang 和 java 慢。对于很多事情来说,这也是一种笨拙的语法。然而,对于大型“事务”,php mysqli 实际上比 golang 快 2 倍,除非你笨拙地生成许多 go-routines 来划分工作。

在我的测试和研究过程中,我发现了一些事情。

PHP mysqli“交易”api 可能正在使用某种批处理操作来完成“交易”,因为 mysqli 没有单独的批处理功能,而且交易比单次插入更快。但在大多数其他语言中,事务不会自动批处理所有内容,甚至不会增加执行时间。它们只是一种机制,可以在出现问题时回滚事务中的所有内容。在其他语言中增加执行时间的是使用批处理。

但是现在 go mysql 接口的一大问题似乎是没有真正支持批处理操作。通过这样做,我能够将 go 的执行时间从 9.2 秒缩短到 3.9 秒,而无需生成其他 go 例程。但是由于没有真正的支持,批处理操作只为批处理的第一个操作返回一个结果集。这对我来说毫无价值,因为我需要为插入的行返回 autoinc ID。此设置还有其他问题,我不会深入探讨。

所以最后我在 tomcat 服务器上尝试了 java。Tomcat/java 的安装比 go 复杂一点,但是用 java 编程要容易得多,也自然得多。JDBC 是一个优秀的驱动程序,完全支持使用准备好的语句进行简单的批处理操作。它仅在 1 秒内完成了 100k 次插入。这是我书中的明显赢家。加上 java 语法比 golang IMO 自然得多。


查看完整回答
反对 回复 2023-05-08
  • 1 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信