はじめてのパフォーマンス改善 with New Relicで年間2520時間を生み出した話

## 追記
Qiita Advent Calendar 2023にてNew Relic賞をいただくことができました！
ご選出いただいたNew Relic様、また記事を読んでくださった皆様、誠にありがとうございました🙇‍♂️
https://blog.qiita.com/adventcalendar-2023-presents-winners/

## はじめに
この記事は[New Relic 使ってみた情報をシェアしよう！ by New Relic Advent Calendar 2023](https://qiita.com/advent-calendar/2023/newrelic) 24日目の記事になります:christmas_tree:

https://qiita.com/advent-calendar/2023/newrelic

今回はDatadogからNew Relicに移行後はじめて、かつ組織にSREポジションができてはじめての**パフォーマンス改善**についてご紹介します。

## この記事で紹介しないこと
* 高度なパフォーマンス改善のノウハウ
* Datadogからの移行ノウハウ

## あらまし
国内最大級のファッションレンタルサービスを展開するエアークローゼットでは、サービスサイトやアプリの他に、倉庫システムなど様々なシステムを自社内製化しています。

なかでも特徴的なのが、スタイリストがオンライン上でお客様に合ったお洋服をお選びする**スタイリング提供システム**です。

https://corp.air-closet.com/news/press-release/170707/

ただ、このシステムにはパフォーマンス面の課題があり、度々スタイリストさんから「**ローディングが長い**」「**サクサク動くようにしてほしい**」といった要望を受けていました。が、優先度が上がらず着手されていませんでした。

そんな中、エアークローゼットでは2023年3月にSREポジションが誕生し、プロダクトの品質や障害対応速度の向上などに立ち向かっていました。パフォーマンスまわりの課題をCTOと棚卸する中で、このスタイリング提供システムのパフォーマンスが話題にあがったのです。

そして、Datadogから移行したばかりの**New Relic**を使い、システムのパフォーマンスを改善していくことが決まりました。

https://newrelic.com/jp

## やったこと
### 1. New Relicでパフォーマンス問題の原因を探る
まずは、パフォーマンス問題のざっくりとした原因を探ります。
New RelicのTransactionsでは、エンドポイント単位のパフォーマンスを見ることができます。ここで、問題の原因がDBにあるのか、アプリケーションの処理にあるのか、外部との通信にあるのかを確認することができます。
![Breakdown table](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/e02cccb9-da8f-e818-34dd-316a3fd6231c.png)

スタイリング提供システムにおいては、ほとんどが**DBの問題**であることがわかりました。そこで、流れているクエリを見てみようとしたのですが...
![Slow SQL traces](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/76bc0c1d-1ea6-fa13-13f9-b2a3a8cb4bd6.png)
クエリがない...だと...?!

### 2. New Relicの設定でクエリ転送設定を有効化する
どうやら、導入時にクエリの転送設定をしていなかったようです。
[ドキュメント](https://docs.newrelic.com/docs/apm/agents/nodejs-agent/installation-configuration/nodejs-agent-configuration/)を参考に、スロークエリの転送設定とTransactionにおけるクエリの転送を設定してみることにしました。

New Relicの設定ファイルで`slow_sql`と`transaction_tracer`を設定することで、簡単に有効化ができました。

![newrelic.js](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/5d3e8a0d-6830-f7db-193f-496b8a63e1ab.png)

リリース後すぐに、以下のようにクエリを確認できるようになります。

![スロークエリの一覧](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/2132a323-e349-87c4-8ab1-57ba23c69f00.png)

![クエリの詳細](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/81b356ad-a51d-5b2f-7300-67c1395e9ccc.png)


### 3. 問題の原因を調査・対策
先ほど確認できたクエリを実際に流してみたり、`EXPLAIN`してみたりして調査を進めました。調査の中で、複雑なクエリや冗長なクエリによってパフォーマンスが低下しているケースはほとんどありませんでした。

お恥ずかしいことに、原因のほとんどは取得・更新のキーに使用しているカラムに**Indexが貼られていなかった**ことでした...。

### 4. 対策を打つ
貼るべきIndexが貼られていなかったこともあり、改善のためのアクションはほとんどが「適切なインデックスを貼ること」でした。
1~2ヶ月を通して7カラムにIndexを貼り、都度その効果を確認していきました。

視覚的にわかりやすく、改善が目に見えてわかるのも非常にありがたいです。
![Top 5 database operation](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/751808/8978e0a8-e75f-17ab-925e-a4169c9281a3.png)

## どのくらいの効果があったの？
結果的に、多くのエンドポイントにおいてパフォーマンスを改善することができました！
| API | 改善前 | | 改善後 | | 改善幅 |
|-----------|-------|--|-------|--|-------|
| A         | 4.34s　 |→| 0.38s | = | 3.96s (91%改善) |
| B 　        | 3.96s |→| 0.37s | = | 3.59s (90%改善) |
| C         | 10.6s |→| 7.41s | = | 3.19s (30%改善) |
| D         | 4.23s |→| 0.57s | = | 3.66s (86%改善) |
| E         | 4.49s |→| 0.74s | = | 3.75s (83%改善) |

トータルすると、**選定1回あたり18.15秒**のパフォーマンス改善になりました。
エアークローゼットでは**年間約500,000回以上**の選定が行われているため、年間にすると実に**約2,520時間分**の選定時間を削減することができました🎉🎉🎉

## まとめ
最後までご覧いただきありがとうございました🙏

[エアークローゼット Advent Calendar 2023](https://qiita.com/advent-calendar/2023/air-closet)もご覧いただけると大変嬉しく思います！
エアークローゼットはエンジニア採用活動も行っておりますので、興味のある方はぜひご覧ください！

https://corp.air-closet.com/recruiting/developers/

https://www.wantedly.com/companies/airCloset/projects