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
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
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
「人を評価する AI」の設計と実装
ryoyanara
0
210
自動化したのに回らない テスト運用の壁―AI時代の品質責任と生産性
mfunaki
0
280
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
470
Flow は今どうなっているか
mizdra
PRO
0
610
AIを紡ぐPMのお話
swdtkuy
0
110
React本体のコードリーディング
high_g_engineer
1
150
変わらないものが、変わるものを決める — 意図駆動開発 × イベントソーシング × イミュータブル | What Doesn't Change Decides What Can — IDD × Event Sourcing × Immutability
tomohisa
0
1.8k
Go言語とトイモデルで学ぶTransformerの気持ち / fukuokago23-transformer
monochromegane
0
180
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
190
メールのエイリアス機能を履き違えない
isshinfunada
0
240
進化を続けるGo toolsの現在地 / The Current State of Ever-Evolving Go Tools
hond0413
0
240
そこに3びきプロダクトがいるじゃろう——生成AI時代における“価値が届かない理由”の構造
kosuket
0
510
Featured
See All Featured
Measuring Dark Social's Impact On Conversion and Attribution
stephenakadiri
2
250
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
45k
Producing Creativity
orderedlist
PRO
348
40k
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.5k
How GitHub (no longer) Works
holman
316
150k
Jamie Indigo - Trashchat’s Guide to Black Boxes: Technical SEO Tactics for LLMs
techseoconnect
PRO
0
620
Measuring & Analyzing Core Web Vitals
bluesmoon
9
960
Primal Persuasion: How to Engage the Brain for Learning That Lasts
tmiket
0
420
The agentic SEO stack - context over prompts
schlessera
0
860
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.3k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.8k
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