Go 数据库技巧:重复利用 Prepare 后的 stmt 来提高 MySQL 的执行效率

Go

在 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 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

原文地址:https://www.manniwood.com/2019_04_28/go_...

译文地址:https://learnku.com/go/t/49736

本帖已被设为精华帖!
本文为协同翻译文章,如您发现瑕疵请点击「改进」按钮提交优化建议
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!