教程

性能

qianmoQqianmoQ· 更新于 2026-09-23· 阅读 7 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

GORM 优化了许多内容以提升性能,默认性能对于大多数应用来说已经足够好,但针对你的应用仍有一些提升性能的技巧。

禁用默认事务

GORM 在事务中执行写操作(创建/更新/删除)以确保数据一致性,但这会影响性能,你可以在初始化时禁用它

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

预编译 SQL 缓存

在执行任何 SQL 时创建预编译语句并缓存它们,以加速后续调用


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


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 Builder

预编译语句同样适用于原始 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,之后再通过预编译语句执行,详情请查看 Session 模式

选择字段

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

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

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

type User struct {
  ID     uint
  Name   string
  Age    int
  Gender string
  
}

type APIUser struct {
  ID   uint
  Name string
}


db.Model(&User{}).Limit(10).Find(&APIUser{})

迭代 / FindInBatches

通过迭代或分批方式查询和处理记录

索引提示

索引 用于加快数据搜索和 SQL 查询性能。索引提示 为优化器提供关于查询处理时如何选择索引的信息,从而可以灵活地选择比优化器更高效的执行计划

import "gorm.io/hints"

db.Clauses(hints.UseIndex("idx_user_name")).Find(&User{})


db.Clauses(hints.ForceIndex("idx_user_name", "idx_user_id").ForJoin()).Find(&User{})


db.Clauses(
  hints.ForceIndex("idx_user_name", "idx_user_id").ForOrderBy(),
  hints.IgnoreIndex("idx_user_name").ForGroupBy(),
).Find(&User{})

读写分离

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

GitHub tag (latest SemVer)

评论

登录后参与评论

正在加载评论…