我一直在测试Go,希望将其用于新站点,并希望确保它与PHP一样快或更快。所以我进行了一个基本测试,在Go和PHP中进行了批量插入,因为我需要批量插入。
我的测试使用事务,准备好的语句,同一台机器,完全相同的表定义,除了PK之外没有索引以及函数中的相同逻辑。
结果:
我正在使用的go mysql驱动程序是在此处找到的最受欢迎的一种“ Go-MySQL-Driver”:https://github.com/go-sql-driver/mysql
我想知道是否有人可以告诉我我编写的代码是否设置正确,或者这到底是怎么回事。
该函数为一些行变量添加了一些可变性,只是每一行都不相同。
转到功能:
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)
}
PHP函数:
function FillTable($num_entries_to_add){
$mysqli= new mysqli("localhost", $GLOBALS['db_username'], $GLOBALS['db_userpass'], $GLOBALS['database_name']);
if ($mysqli->connect_errno == 0) {
$int_a = 9;
$int_b = 4;
$int_01 = 1;
$int_02 = 1451628000; // Date Entered (2016-1-1, 1am)
$int_03 = 11;
$int_04 = 0;
$int_05 = 0;
$float_01 = 90.0; // Value
$float_02 = 0;
$float_03 = 0;
$text_01 = "";
$text_02 = "";
$text_03 = "";
$mysqli->autocommit(FALSE); // This Starts Transaction mode. It will end when you use mysqli->commit();
$sql = "INSERT INTO " . $GLOBALS['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 (?,?,?,?,?,?,?,?,?,?,?,?,?)";
$start_time = microtime(true);
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param('iiiiiiidddsss', $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);
$flip = 0;
for ($i = 1; $i <= $num_entries_to_add; $i++) {
$flip = ((int)($i / 500)) % 2;
if ($flip == 0) {
$float_01 += .1; // add Value
}
else {
$float_01 -= .1; // sub Value
}
$int_02 += 1; // add a second to date.
$stmt->execute(); //Executes a prepared Update
}
$mysqli->commit(); // Transaction mode ends now
$stmt->close(); //Close statement
}
$execute_time = microtime(true) - $start_time;
echo $GLOBALS['html_newline'] . $GLOBALS['html_newline'] .
'FillDataEntryTable Speed: '.$execute_time.' sec' . $GLOBALS['html_newline'] . $GLOBALS['html_newline'];
$thread_id = $mysqli->thread_id; // Get MySQL thread ID
$mysqli->kill($thread_id); // Kill MySQL Server connection
$mysqli->close(); // Close MySQL Server connection
}
}
答案 0 :(得分:0)
在测试中,我想为新网站使用哪种语言,我尝试了php,golang和java。我对任何一种语言都没有太多的经验,因此我将来在这里所说的任何事情都可能会被将来的人纠正。
我的主要测试是将批处理插入到mysql数据库中,因为我将在应用程序中使用它。
我想摆脱php,因为它是一种未编译的旧脚本语言,在许多方面比golang和Java慢。对于许多事情来说,这也是一个笨拙的语法。但是,对于大型“交易”,php mysqli实际上比golang快2倍,除非您笨拙地生成许多go例程来划分工作。
在测试和研究过程中,我发现了一些问题。
PHP mysqli“事务” API可能正在使用某种批处理操作来完成“事务”,因为mysqli没有单独的批处理功能,并且事务处理比单个插入要快。但是在大多数其他语言中,事务不会自动分批处理所有事务,甚至不会增加执行时间。它们只是在发生问题时回滚事务中所有内容的机制。使用其他语言增加执行时间的原因是使用批处理。
但是现在使用mysql接口的主要问题之一似乎是对批处理操作没有真正的支持。我最近得到的是杰里(Jerry)钻机之一,并按照本文(golang - mysql Insert multiple data at once?)的说明进行了自己的批处理操作。这样做,我能够在不产生其他go例程的情况下将执行时间从9.2s缩短到3.9s。但是由于没有真正的支持,因此批处理操作只会为批处理的第一个操作返回一个结果集。这对我来说毫无价值,因为我需要为插入的行返回autoinc Ids。此设置还有其他问题,我将不涉及。
所以最后我在tomcat服务器上尝试了java。 Tomcat / java的安装比进行安装要复杂得多,但是用Java进行编程非常容易和自然。 JDBC是出色的驱动程序,它完全支持通过准备好的语句进行简单的批处理操作。仅1秒就完成了10万次插入。这是我书中明显的赢家。再加上Java语法比golang IMO更自然。