性能

GORM 优化了许多方面以提高性能,默认性能应该适合大多数应用程序,但仍有一些技巧可以提高应用程序的性能。

禁用默认事务

GORM 在事务中执行写操作(创建/更新/删除)以确保数据一致性,这对性能不利,您可以在初始化期间禁用它

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
SkipDefaultTransaction: true,
})

缓存预处理语句

在执行任何 SQL 时创建预处理语句并缓存它们以加速未来的调用

// Globally mode
db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
PrepareStmt: true,
})

// Session mode
tx := db.Session(&Session{PrepareStmt: true})
tx.First(&user, 1)
tx.Find(&users)
tx.Model(&user).Update("Age", 18)

注意 还请参考如何为 MySQL 启用 interpolateparams 以减少往返 https://github.com/go-sql-driver/mysql#interpolateparams

使用 PreparedStmt 的 SQL 构建器

Prepared Statement 也适用于 RAW SQL,例如

db, err := gorm.Open(sqlite.Open("gorm.db"), &gorm.Config{
PrepareStmt: true,
})

db.Raw("select sum(age) from users where role = ?", "admin").Scan(&age)

您还可以使用 GORM API 使用 DryRun 模式 准备 SQL,并在稍后使用预处理语句执行它,请查看 会话模式 了解更多详细信息

选择字段

默认情况下,GORM 在查询时选择所有字段,您可以使用 Select 指定您想要的字段

db.Select("Name", "Age").Find(&Users{})

或者定义一个更小的 API 结构体来使用 智能选择字段功能

type User struct {
ID uint
Name string
Age int
Gender string
// hundreds of fields
}

type APIUser struct {
ID uint
Name string
}

// Select `id`, `name` automatically when query
db.Model(&User{}).Limit(10).Find(&APIUser{})
// SELECT `id`, `name` FROM `users` LIMIT 10

迭代 / 分批查找

使用迭代或分批查询和处理记录

索引提示

索引 用于加速数据搜索和 SQL 查询性能。 索引提示 为优化器提供有关如何在查询处理期间选择索引的信息,这使得可以选择比优化器更有效的执行计划

import "gorm.io/hints"

db.Clauses(hints.UseIndex("idx_user_name")).Find(&User{})
// SELECT * FROM `users` USE INDEX (`idx_user_name`)

db.Clauses(hints.ForceIndex("idx_user_name", "idx_user_id").ForJoin()).Find(&User{})
// SELECT * FROM `users` FORCE INDEX FOR JOIN (`idx_user_name`,`idx_user_id`)"

db.Clauses(
hints.ForceIndex("idx_user_name", "idx_user_id").ForOrderBy(),
hints.IgnoreIndex("idx_user_name").ForGroupBy(),
).Find(&User{})
// SELECT * FROM `users` FORCE INDEX FOR ORDER BY (`idx_user_name`,`idx_user_id`) IGNORE INDEX FOR GROUP BY (`idx_user_name`)"

读写分离

通过读写分离提高数据吞吐量,请查看 数据库解析器

铂金赞助商

黄金赞助商

铂金赞助商

黄金赞助商