为多个请求准备一次 SQL 语句可以吗?
Is it okay to prepare SQL statement once for multiple request?
我有一些 SQL 查询不会在每次请求时改变(只有它的参数)。因此,不是为每个请求都这样做:
func HandleRequest() {
rows, err := db.Query(sqlQuery, params...)
// do something with data
}
如果每次请求我都这样做可以吗:
// together with server initialization
stmt, err := db.Prepare(sqlQuery)
func HandleRequest() {
rows, err := stmt.Query(params...)
// do something with data
}
正如 DB.Prepare()
的文档所述:
Multiple queries or executions may be run concurrently from the returned statement.
并发使用是安全的,尽管 intended 准备语句的用途不是在多个请求之间共享它们。主要原因是准备好的语句(可能)在数据库服务器本身中分配资源,并且在您调用返回语句的 Close()
方法之前它不会被释放。所以我建议不要这样做。
典型的用例是如果您必须 运行 使用不同的参数多次执行相同的语句,例如文档中的示例:
projects := []struct {
mascot string
release int
}{
{"tux", 1991},
{"duke", 1996},
{"gopher", 2009},
{"moby dock", 2013},
}
stmt, err := db.Prepare("INSERT INTO projects(id, mascot, release, category) VALUES( ?, ?, ?, ? )")
if err != nil {
log.Fatal(err)
}
defer stmt.Close() // Prepared statements take up server resources and should be closed after use.
for id, project := range projects {
if _, err := stmt.Exec(id+1, project.mascot, project.release, "open source"); err != nil {
log.Fatal(err)
}
}
我有一些 SQL 查询不会在每次请求时改变(只有它的参数)。因此,不是为每个请求都这样做:
func HandleRequest() {
rows, err := db.Query(sqlQuery, params...)
// do something with data
}
如果每次请求我都这样做可以吗:
// together with server initialization
stmt, err := db.Prepare(sqlQuery)
func HandleRequest() {
rows, err := stmt.Query(params...)
// do something with data
}
正如 DB.Prepare()
的文档所述:
Multiple queries or executions may be run concurrently from the returned statement.
并发使用是安全的,尽管 intended 准备语句的用途不是在多个请求之间共享它们。主要原因是准备好的语句(可能)在数据库服务器本身中分配资源,并且在您调用返回语句的 Close()
方法之前它不会被释放。所以我建议不要这样做。
典型的用例是如果您必须 运行 使用不同的参数多次执行相同的语句,例如文档中的示例:
projects := []struct {
mascot string
release int
}{
{"tux", 1991},
{"duke", 1996},
{"gopher", 2009},
{"moby dock", 2013},
}
stmt, err := db.Prepare("INSERT INTO projects(id, mascot, release, category) VALUES( ?, ?, ?, ? )")
if err != nil {
log.Fatal(err)
}
defer stmt.Close() // Prepared statements take up server resources and should be closed after use.
for id, project := range projects {
if _, err := stmt.Exec(id+1, project.mascot, project.release, "open source"); err != nil {
log.Fatal(err)
}
}