There are a lot of nuances of speed test in mysql between golang and other languages.
At first, the settings of mysql is important. Multithread or singletread, cache etc.
Then we can remember, that the same queries are cached in mysql (we can say - shadow prepare)
Then we can remember, that golang has goroutings. Therefore we can easy to create an overload, because we has limit of tcp stack (and socket also) in system. And limit of database connections also.
Then the great influence has package size - row size.
In general, golang program is faster then php always.
For example php utility
<?php
$dsn = 'mysql:dbname=gotest;host=127.0.0.1';
$user = 'root';
$password = 'corner';
$item = 0;
$value = 'Lorem ipsum dolor';
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection fault: ' . $e->getMessage();
}
$SQLQuery = "INSERT INTO `foo` (`item`,`itemval`) VALUES(?,?)";
$stmt = $dbh->prepare($SQLQuery);
$time_start = microtime_float();
for ($i=0; $i < 1000000; $i++) {
$stmt->bindParam(1, $i);
$stmt->bindParam(2, $value);
$stmt->execute();
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "Exec time $time seconds".PHP_EOL;
$speed = 1000000.00/$time;
echo "Speed $speed per second".PHP_EOL;
has speed on i7-4702MQ 16Gb SSD 850pro 13134 records per second
And golang utiliity
package main
import (
"database/sql"
"fmt"
"log"
"runtime"
"sync"
"time"
_ "github.com/go-sql-driver/mysql"
)
// Foo test data
type Foo struct {
Key int
Val string
}
const (
VAL = `Lorem ipsum dolor`
)
var (
DBW *sql.DB
DSN = "root:corner@tcp(127.0.0.1:3306)/gotest?charset=utf8"
SQLQuery = "INSERT INTO `foo` (`item`,`itemval`) VALUES(?,?)"
StmtMain *sql.Stmt
wg sync.WaitGroup
)
func Store(d Foo) {
defer wg.Done()
_, err := StmtMain.Exec(d.Key, d.Val)
if err != nil {
log.Fatalln(err)
}
}
func main() {
var (
errDbw error
errStmt error
)
concurrencyLevel := runtime.NumCPU() * 8
DBW, errDbw = sql.Open("mysql", DSN)
if errDbw != nil {
log.Fatalln(errDbw)
}
DBW.SetMaxIdleConns(concurrencyLevel)
defer DBW.Close()
StmtMain, errStmt = DBW.Prepare(SQLQuery)
if errStmt != nil {
log.Fatalln(errStmt)
}
defer StmtMain.Close()
//populate data
dd := Foo{
Key: 0,
Val: VAL,
}
t0 := time.Now()
for i := 0; i < 1000000; {
for k := 0; k < concurrencyLevel; k++ {
i++
if i > 1000000 {
break
}
dd.Key = i
wg.Add(1)
go Store(dd)
}
wg.Wait()
if i > 1000000 {
break
}
}
t1 := time.Now()
fmt.Printf("%v per second.\n", 1000000.0/t1.Sub(t0).Seconds())
}
has speed 26255 records per second
As you see, we prevent shadow prepare (query cache) by set key as number.
Also we can adjust max speed by change concurrency level until our database will work stable.
You can increase this value until database reject connections.
As you can see, a lot of nuances are important in every situation.
Also, you can see that database settings is very important
And in fine
you can experiment with PCNTL Functions in PHP 