go 数据库技巧:重复利用 prepare 后的 stmt 来提高 mysql 的执行效率 | go优质外文翻译 | go 技术论坛-大发黄金版app下载
在 go 中重复利用 prepare 返回的 stmt 语句能够优化多少时间?
以下这个简单的实验能够给你一个粗略的答案。
我们知道,在 sql 语句中使用参数时,go 的 sql
包使用的是 prepare 模式。
就像下面这段代码:
err = db.queryrow("select count(*) from pg_stat_activity where datname = $1", "postgres").scan(&num)
如果你打开了 sql 语句日志功能,执行上面代码会打印如下日志:
log: execute : select count(*) from pg_stat_activity where datname = $1
detail: parameters: $1 = '42'
使用下面程序执行上面的基础查询语句1000次:
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/lib/pq"
)
func main() {
db, err := sql.open("postgres", "postgres://postgres:postgres@localhost/postgres?sslmode=disable")
if err != nil {
log.fatal(err)
}
var num int
start := time.now()
for i := 0; i < 1000; i {
err = db.queryrow("select count(*) from pg_stat_activity where datname = $1", "postgres").scan(&num)
if err != nil {
log.fatal(err)
}
}
elapsed := time.since(start)
fmt.printf("got: %d in %s\n", num, elapsed)
}
这是通过上述程序的 5 次运行得到的结果:
got: 1 in 411.181744ms
got: 1 in 421.445645ms
got: 1 in 452.958473ms
got: 1 in 419.599104ms
got: 1 in 432.694446ms
现在让我们尝试一个略微复杂一些的程序,我们预先准备该语句,然后重复使用1000次来替代之前:
package main
import (
"database/sql"
"fmt"
"log"
"time"
_ "github.com/lib/pq"
)
func main() {
db, err := sql.open("postgres", "postgres://postgres:postgres@localhost/postgres?sslmode=disable")
if err != nil {
log.fatal(err)
}
defer db.close()
stmt, err := db.prepare("select count(*) from pg_stat_activity where datname = $1")
if err != nil {
log.fatal(err)
}
defer stmt.close()
var num int
start := time.now()
for i := 0; i < 1000; i {
err = stmt.queryrow("postgres").scan(&num)
}
elapsed := time.since(start)
fmt.printf("got: %d in %s\n", num, elapsed)
}
我们得到的查询时间大约快三倍半:
got: 1 in 115.087555ms
got: 1 in 121.813083ms
got: 1 in 121.280645ms
got: 1 in 122.50746ms
got: 1 in 125.474026ms
显然,重复利用 prepare 后的 stmt 语句,可以有效提高 sql 执行性能。
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 cc 协议,如果我们的工作有侵犯到您的权益,请及时联系大发黄金版app下载。
原文地址:
本帖已被设为精华帖!