4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GORMと素のSQLの実装のパフォーマンスの差をユースケース毎に比較してみた

4
Last updated at Posted at 2026-03-03

go college3日目に参加してまいりました。今回はデータベース周りのことを勉強しました。そこでgormと素のSQLクエリで実装した際に、どのくらいパフォーマンスに差が生まれるのかというところが気になりました。

前提

今回は単純にユースケース毎にGORMとSQLでの違いを図りたいだけなので、

  • スループット、
  • 一回の処理当たりの時間比較
  • 単位時間当たり

を比較をすることにしました。
両者の間に差が生まれるのはなぜか?の部分は今回は考えないことにします。

仮説

1:単発クエリでは差が出る

コードを見たところgormではCreate()でも複数処理を行っています

なので単発では処理時間に大きく差が出ると予想しました

2:大量フェッチ,高負荷では差が縮む

大量フェッチとなるとボトルネックはDB側、Disk I/oなどになり、支配要因が変わると考えました

調べたユースケース

  1. GetUserByID: usersをidで1件
  2. ListPostsByUser: user_idでpostsをcreated_at descでlimit 20
  3. ListPostsWithCommentsCount: postsとcommentsを集計(join+group)してlimit 50
  4. CreatePostWith2CommentsTx: 1Txでpost insert + comment 2件 insert
  5. UpdatePostStatus: status更新(where id=?)

検証結果

2026/03/03 20:47:34 benchmark initialized: users=2000 posts=20042
goos: linux
goarch: amd64
pkg: benchmark
cpu: AMD Ryzen 5 7530U with Radeon Graphics         
BenchmarkGetUserByID/raw_sql-12                      876           1310943 ns/op               762.8 ops/s          1515 B/op         39 allocs/op
BenchmarkGetUserByID/gorm-12                         925           1256619 ns/op               795.8 ops/s          4961 B/op         84 allocs/op
BenchmarkListPostsByUser/raw_sql-12                  853           1421061 ns/op               703.7 ops/s          4110 B/op        156 allocs/op
BenchmarkListPostsByUser/gorm-12                     862           1331018 ns/op               751.3 ops/s         11058 B/op        276 allocs/op
BenchmarkListPostsWithCommentsCount/raw_sql-12                 6         184076876 ns/op                 5.433 ops/s       10920 B/op        514 allocs/op
BenchmarkListPostsWithCommentsCount/gorm-12                    6         178349810 ns/op                 5.607 ops/s       41466 B/op        932 allocs/op
BenchmarkCreatePostWith2CommentsTx/raw_sql-12                151           7647868 ns/op               130.8 ops/s          1870 B/op         44 allocs/op
BenchmarkCreatePostWith2CommentsTx/gorm-12                   140           7826742 ns/op               127.8 ops/s         13442 B/op        155 allocs/op
BenchmarkUpdatePostStatus/raw_sql-12                         666           1868220 ns/op               535.3 ops/s           359 B/op         13 allocs/op
BenchmarkUpdatePostStatus/gorm-12                            207           6829219 ns/op               146.4 ops/s          6720 B/op         80 allocs/op
PASS
ok      benchmark       19.55

1.GetUserByID

予想通り、単発クエリでは差が出ました。

特にスループットを見るとrawSQLの方が低く、やはりgORMの内部処理分だけオーバーヘッドが存在していると考えられます。またallocs/opを見ると、

- raw SQL: 39 allocs/op  
- GORM: 84 allocs/op 

となっており、GORM側ではメモリアロケーションが約2倍発生していました。
今回の結果から、単純に1件取得するようなケースでは、gORMの内部処理の分だけコストが追加されることが確認できました。
しかしns/op自体は大きな差にはならなかったため、実際にはDBアクセス時間の影響も大きいと感じました。

2. ListPostsByUser

このケースでは予想とは少し異なり、大きな差は見られませんでした。
スループット・処理時間ともにほぼ同程度で、むしろ GORM の方がわずかに良い結果になっています。
大量データ取得になると、

  • DB 側の処理
  • データ転送
  • ソート処理

などの影響が強くなり、アプリケーション側の実装差が目立たなくなると考えられます。
一方でallocs/opは依然としてGORMの方が多く、内部で追加処理が行われていることは確認できました。

3. ListPostsWithCommentsCount

JOINとGROUP BYを含む集計クエリでは、両者の差はほぼありませんでした。
処理時間はどちらも約180ms程度となり、gormとrawSQLの違いはほとんど見られませんでした。
このケースでは明らかにボトルネックがDB側にありGo側の処理差は結果にほぼ影響しないと考えられます。
ただしメモリ使用量を見ると、GORMの方がallocs/opが多くなっており、内部処理のコスト自体は存在していることが分かります。

4. CreatePostWith2CommentsTx

トランザクションを含むinsert処理では、両者の差はかなり小さくなりました。
処理時間はほぼ同じであり、トランザクションコミットやDB書き込み処理がボトルネックになっていると考えれます。
そのためwrite処理ではgormを使用してもパフォーマンス差は大きくならないと感じました。
ただしallocs/opはGORMの方が多く、アプリケーション側の処理量は増えていることが確認できます。

5. UpdatePostStatus

今回もっとも差が出たのがこのケースでした。

  • raw SQL: 約1.8ms
  • GORM: 約6.8ms

となり、GORMの方が大きく時間がかかる結果となりました。
単純な更新処理ではDB側の処理が軽いため、gormの内部処理コストがそのまま処理時間の差として現れたと考えられます。


まとめ

今回の検証結果は

  • 単純な1件取得や更新では差が出やすい
  • データ量が増えるほど差は小さくなる
  • JOINやトランザクションを含む処理ではほぼ差がなくなる

となりました。
ORM の影響が大きく出るのはアプリケーション側の処理時間が支配的なケースであり、DB 処理が重くなるほど差は小さくなるという結果になりました。

感想

今回実際に計測してみて、gormの内部処理のコストはユースケースによって影響度が変わることが分かりました。
特に単純な更新や高頻度で呼ばれる処理では素のSQLを使うメリットがありそうですが、複雑なクエリやトランザクションを伴う処理ではGORMを使っても大きな問題はないと感じました。

使用したコード:

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?