效能

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 建構器

已準備好的陳述式也適用於 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 準備 SQL,並使用 DryRun 模式,稍後再使用已準備好的陳述式執行它,請查看 Session 模式 以取得詳細資訊

選取欄位

預設情況下,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

反覆運算 / FindInBatches

使用反覆運算或批次查詢和處理記錄

索引提示

索引用於加速資料搜尋和 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`)"

讀取/寫入分離

透過讀寫分離增加資料傳輸量,請查看資料庫解析器

白金贊助商

黃金贊助商

白金贊助商

黃金贊助商