sql使用带占位符或不带占位符的测试
见a,b处代码
func QueryPrepare(db *sql.DB) (int, error) {
const sqlText = "select age from nation where id = ?" // a. 此处?就是占位符。
var count int
err := db.QueryRow(sqlText, 1).Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
func QueryNonPrepare(db *sql.DB) (int, error) {
const sqlText = "select age from nation where id = 1" // b. 直接使用值,而非占位符。
var count int
err := db.QueryRow(sqlText).Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
基准压测代码
DB是数据库句柄。
func BenchmarkQueryPrepare(b *testing.B) {
for i := 0; i < b.N; i++ {
QueryPrepare(DB)
}
}
func BenchmarkQueryNonPrepare(b *testing.B) {
for i := 0; i < b.N; i++ {
QueryNonPrepare(DB)
}
}
结果
go test -bench=. -benchmem
BenchmarkQueryPrepare 2936 428610 ns/op 648 B/op 21 allocs/op
BenchmarkQueryPrepare-2 2614 421596 ns/op 648 B/op 21 allocs/op
BenchmarkQueryPrepare-4 2797 412198 ns/op 648 B/op 21 allocs/op
BenchmarkQueryPrepare-8 2406 415762 ns/op 648 B/op 21 allocs/op
BenchmarkQueryNonPrepare 6015 231139 ns/op 432 B/op 13 allocs/op
BenchmarkQueryNonPrepare-2 4813 237164 ns/op 432 B/op 13 allocs/op
BenchmarkQueryNonPrepare-4 4813 250533 ns/op 432 B/op 13 allocs/op
BenchmarkQueryNonPrepare-8 4454 242844 ns/op 432 B/op 13 allocs/op
结论
非占位符性能高于占位符近似一倍
从以上基准结果来看,使用占位符与不使用占位符有明显的性能差异。
占位符之所以性能有所下降是因为需要多一次与数据库的交互,而且连接db时使用锁。
建议
- 占位符主要作用是防SQL注入。如登陆,必须使用注入操作。
- 如果普通查询,参数过滤严格,可以不使用占位符操作。这样性能更佳
网友评论