Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
20220319[Laravel]想定外のN+1アラート
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
kuma
March 14, 2022
Programming
200
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
20220319[Laravel]想定外のN+1アラート
kuma
March 14, 2022
More Decks by kuma
See All by kuma
エンジニアの輪スライド
kumainataku
0
290
20220730[PHP]デザインパターン色々学んでみた
kumainataku
0
150
20220227 可読性って大事
kumainataku
0
86
20211027_僕の転職活動の振り返り.pdf
kumainataku
0
120
オブジェクト指向(超基礎)
kumainataku
0
160
20210516 LT資料(PHP echo print)
kumainataku
0
60
20210425 LT会(基本情報技術者)
kumainataku
0
50
202104 読書LT会
kumainataku
0
220
Other Decks in Programming
See All in Programming
仕様駆動開発の消費期限
watany
20
8.6k
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
290
AWS DevOps AgentのAzure接続機能を検証して見えた活用法/Use Cases Verified for the AWS DevOps Agent's Azure Connectivity Feature
masakiokuda
1
240
GDG Korea Android: 2026 I/O Extended ~ What's new in Android development tools
pluu
0
230
SlackアプリとLambdaの 連携を構築した話
pawn_4_s
1
120
実装をデザインガイドラインに追従させるための取り組み / 260731-dip-mosh-design-system
dachi023
0
3.7k
AIを紡ぐPMのお話
swdtkuy
0
110
freeeにおけるEvalsの実践例の紹介
freee
PRO
0
120
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
110
freee が目指す データ マネジメント戦略 AI-Ready 時代を支える 攻めのガバナンスとは
freee
PRO
0
410
Google Apps Script で Ruby を動かす
kawahara
0
270
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.9k
Featured
See All Featured
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.4k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Writing Fast Ruby
sferik
630
63k
The Cult of Friendly URLs
andyhume
79
7k
Navigating Algorithm Shifts & AI Overviews - #SMXNext
aleyda
1
1.6k
The Spectacular Lies of Maps
axbom
PRO
1
920
Navigating Weather and Climate Data
rabernat
0
480
Tips & Tricks on How to Get Your First Job In Tech
honzajavorek
1
700
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
370
We Are The Robots
honzajavorek
0
300
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.3k
Test your architecture with Archunit
thirion
1
2.3k
Transcript
[Laravel]想定外のN+1アラート 2022 / 3 / 19 クマ
自己紹介 • 実務入って半年 • PHP(Laravel)、JavaScript(Vue)を書いてます。 • 好き↓ • タガが外れたように満腹まで食べる •
ラーメン屋のハシゴ、二郎系マシマシ…etc • 甘いもの • ミスド食べ放題いったり、パンケーキ食らったり • スイパラ行くのが直近目標 P-01
目次 • 話すこと • 前提(こっから本題) • やりたいこと • 起きたこと •
原因 • やったこと(本題おわり) • おわりに P-01
話すこと P-01
話す事 LaravelにてN+1が発生していないように見えたのだが、アラート が出たときの対応方法 ↓こんなの ※Laravel経験がないとイメージつきにくい内容かもです。。。 P-01
前提 P-01
前提 バージョン • PHP 8.0.2 • Laravel 8.5.0 P-01
前提 テーブル構成 P-01 blockedプロパティをチェックしてBANす るか否かをチェックする想定
前提 リレーション ↓Userモデル P-01 UserとUserAttributeで1対1のリレーションを構築
やりたいこと P-01
やりたいこと いわゆる「垢BAN機能」を実装したい 特定ユーザーをログインできなくする、アレです。 ※ちなみに、この機能自体は本題と関係ないです。 P-01
やりたいこと <?php namespace App¥Http¥Middleware; use Closure; use Illuminate¥Http¥Request; use Illuminate¥Support¥Facades¥Auth;
class CheckBlockedUser { public function handle(Request $request, Closure $next) { if (Auth::check() && $user = Auth::user()) { $userAttribute = $user->userAttribute; // ※ if ($userAttribute && $userAttribute->blocked == 1) { Auth::logout(); $request->session()->regenerateToken(); Log::notice('Block user from login status. '.$user->id); return redirect()->route('login') ->withErrors(['error' => 'アカウントは凍結されています。']); } } return $next($request); } } P-01 App/Middleware/CheckBlockedUser userAttributeを取得 ➡ここでクエリが発行 (SELECT * FROM user_attribute …) ※補足 ここでblockedプロパティをチェックして BANするか否かをチェック
起きたこと P-01
起きたこと • ブロックユーザーで動作テスト ➡垢BAN機能は実装done(よしよし。) • 正常ユーザー(非ブロックユーザー)での動作テスト ➡ログインできるが、以下アラート発生(おん!?) P-01
起きたこと • このアラートはN+1を勝手に検出して教えてくれるライブラリ 「laravel-query-detector」によるもの • 要約:「User経由でUserAttributeを取得するクエリが必要以 上に実行されているからEager Loadingしてね!」 P-01
やりたいこと class CheckBlockedUser { public function handle(Request $request, Closure $next)
{ if (Auth::check() && $user = Auth::user()) { $userAttribute = $user->userAttribute; // ※ if ($userAttribute && $userAttribute->blocked == 1) { Auth::logout(); $request->session()->regenerateToken(); Log::notice('Block user from login status. '.$user->id); return redirect()->route('login') ->withErrors(['error' => 'アカウントは凍結されています。']); } } return $next($request); } } P-01 App/Middleware/CheckBlockedUser(再掲) ここでしかクエリ発行していないんですが、、、 ただ、、、 ➡原因調査
原因 P-01
原因 P-01 おなじみのLaravel-debugbarで確認したところすぐに判明
原因 P-01 原因はMiddlewareと別でControllerでも同じようなuserAttribute の取得(クエリの実行)をしていた $user = User::find(Auth::id()); // ココでuserAttributeを取得するSQLが発行 $userAttribute
= $user->userAttribute; App/Controller/TestController(実際のコード)
原因 P-01 Laravelとしては 「Middlewareで$userAttributeを取得するよ」 「あれ、Controllerでも取得しているね。だったらN+1だね」 と判断しちゃうんだな。。。 ↓アラート発生時のクエリ(イメージ) SELECT * FROM
use_attribute; … … SELECT * FROM use_attribute; // 2回同じクエリが発行
やったこと P-01
やったこと 案は2つ。 1, Middlewareで取得した$userAttributeをControllerまで渡す? ➡現実的ではない。 2, アラートを表示させない ➡これで行く P-01
やったこと 特定条件下でN+1を検出してもアラートを表示させないようにする ➡具体的にはlaravel-query-detector をインストールした時に入っ てくるconfig/querydetector.phpのexceptの箇所に以下記述 ➡無事アラートは発生しなくなった! P-01 'except' => [
User::class => [ UserAttribute::class, 'userAttribute', ], ] App/Controller/TestController(追加したコード) 今回はUser➡userAttributeの際にN+1が発生し たので、このように記述
おわりに P-01
おわりに • 自分はdevelopとの差分だけ見て「N+1起こるわけな い!」と決めつけた結果痛い目にあった。。。 • どんなことでも共通するのは「自分の修正した差分だ けに問題が潜んでいるとは限らない」ということ →ある程度問題に取り組んで解決しなければ、視野を広 げる(抽象度を上げる)ことの重要性を痛感 P-01
ご清聴ありがとうございました。 P-01