パフォーマンス

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

プリペアードステートメントを使用した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を使用して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

反復処理/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`)"

読み書き分離

読み書き分離によってデータスループットを向上させます。データベースレゾルバーを確認してください。

プラチナスポンサー

ゴールドスポンサー

プラチナスポンサー

ゴールドスポンサー