Closed8

Prisma チューニング戦記

Taichi MasuyamaTaichi Masuyama

背景

複雑な条件の検索ページネーション API を作っている。
今の所以下が課題になりそう。

  • テーブルを跨いで検索するので JOIN が発生してメモリ使用率が高くなる
  • JSON フィールドへの検索があるのでそこは遅くなりそう

やりたいこと

Prisma で発行されたクエリとそのパフォーマンスを見て正しく問題箇所を発見し、対応策を打ちたい。

なんとなく、ORM でクエリを組む時点で細かいチューニングは難しそうなイメージがあるが、今の Prisma ではどこまでできるのか?
どういうケースだと対応できないのか?
ここら辺の解像度を上げたい。

Taichi MasuyamaTaichi Masuyama

https://www.prisma.io/docs/orm/prisma-client/queries/query-optimization-performance

公式。なんか情報少なめか。

https://www.prisma.io/docs/optimize

Prisma Optimize. helps you generate insights and provides recommendations that can help you make your database queries faster.

やってみようぜよ。

今の所考えられるチューニング方法は

  • Raw query 書く
  • 最適化されたクエリを View にして ORM と Raw SQL の中間をとる
  • マテリアライズドビューで JOIN や集計を省く
  • 🆕 Prisma Optimize でなんかいい感じにできるかも

などか。
index 見直すとかそもそも仕様変えるとか他にも色々打ち手はある。

Taichi MasuyamaTaichi Masuyama

Prisma Optimize

https://www.prisma.io/docs/optimize/getting-started
簡単に設定して始められる。
ローカルからでも問題なく使えた

触った感じメモ

できること

  • Latency とレコード数を起点に重いクエリを見ることができる
    • 実際の SQL の形も見ることができる
  • グルーピングされたのを見ることができる
  • Recommendations でチューニング案を出してくれる

感想

  • ただ遅いクエリがあることとそのクエリの特定までしかできない
    • ルールを作れない
    • 検索できない
    • クエリの計画を見れない
  • リッチでダッシュボードで見られて楽ではある
  • 本番で使うのはきつそうだけど、本当にサクッと遅いクエリがあるかどうか見たい時にローカルで使う分には便利かもしれない(?)
Taichi MasuyamaTaichi Masuyama

ローカルで DB のメモリ使用率を確認する

なぜローカルでやるか?

  • テスト環境にあげるのが手間 (少なくとも今は)
  • テスト環境は Cloud SQL で、Query insights と Cloud SQL の監視ダッシュボードを使っての検証になるが、Query insights は 4500 文字を超えるクエリの計画を見ることができない制約があるのでこの際ローカルで分析できるようにしたい

やること

  • ローカルの PostgreSQL のメモリ使用率を監視できるようにする
  • どのクエリが多くのメモリを使ったかを特定する
  • ローカルの PostgreSQL で slow query log を設定する
    • できれば自動で EXPLAIN までして、ファイルに出力するようにしたい
Taichi MasuyamaTaichi Masuyama

ローカルの postgres コンテナのメモリ使用率を監視する

1. まず本番環境と同じ CPU, Memory を設定する

docker-compose.yaml
db:
    image: postgres
...
    mem_limit: 8g
    cpu_count: 2
...

docker desktop でそもそも 8g のメモリと 2コアの cpu を使えるようにリソース設定をしておく。

2. コンテナのリソースを監視する

https://www.docker.com/blog/how-to-monitor-container-memory-and-cpu-usage-in-docker-desktop/
この docker 公式の extension を使ってみる。

コンテナごとに見ることができないので、複数コンテナ使う場合は別の手法が必要になりそう。
幸い今は postgres コンテナだけなので一旦は耐え。
けどせっかくなので別の手段も少し探ってみる。

理想は、クエリを叩いてからレスポンスを受け取るまでのメトリクスの変化を分けて出力できるツールがあればいいかも。

  1. SQL の全貌
    1. の EXPLAIN 結果
  2. クエリによる PostgreSQL のメトリクスの変化 (CPU usage, Memory usage など)
    この3つを1コマンドで出力してくれる的な。

1, 2 は簡単にできそう。

Taichi MasuyamaTaichi Masuyama

これ、Query insights を自分で作るみたいな話になってきたな。
ちょっととまろ。

Query insights alternatives とかでググるなど。

Taichi MasuyamaTaichi Masuyama

4500 文字の制限はありつつも、クエリが切り落とされるだけで計画は見れた(謎)
ので、ローカルでやるモチベーションはかなり減った。

このスクラップは2024/09/14にクローズされました