Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
N+1問題について調べてみた
Search
Yuxki
July 01, 2024
26
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
N+1問題について調べてみた
N+1問題について調べてみた
Yuxki
July 01, 2024
More Decks by Yuxki
See All by Yuxki
TypeScriptのクロージャで型エ ラーにハマった話
yuxki
0
32
Conoha VPSでIaCはできる!!!
yuxki
0
240
個人ブログ作ってデプロイしました。
yuxki
0
62
チームでプロダクトを作る機会でタスクの自走に役立った、個人開発の経験や習慣。
yuxki
0
61
Featured
See All Featured
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
600
Everyday Curiosity
cassininazir
0
360
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Building an army of robots
kneath
307
47k
A Soul's Torment
seathinner
8
3.8k
Believing is Seeing
oripsolob
1
250
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
Testing 201, or: Great Expectations
jmmastey
46
8.3k
Accessibility Awareness
sabderemane
1
250
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
460
Into the Great Unknown - MozCon
thekraken
41
2.8k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Transcript
N+1問題について調べてみた Yukihiro Uejo 1
自己紹介 • 自己紹介 ◦ エンジニア職への就職(アプリのバックエンド)を目指して、日々勉強中です。 経験者と初心者の中間くらいだと思ってます。(実務2年 →個人開発3年) ▪ 実務2年では、主にJavaとSQLで管理会計のWEBアプリを開発 ▪
個人開発では、主にセキュリティと VPSでオンプレっぽくインフラを勉強して いました。 ◦ Vimmer ◦ Go,Python,TypeScript ◦ 委託開発先ではバックエンドの開発をやってます。 ▪ 約半年生き残りました!🎉🎉🎉 2
「N+1問題」について調べようと思ったきっかけ • ORMで、N(N(N+1)+1)+1みたいなことをしているのを見かけて、クエリが 爆発的に増加していたところに出くわしたから。 • 以前の発表でもN+1というワードが出てきて、「?」となったので、調べて みることにした。 3
「N+1問題」の概要 N + 1 1回SELECT句を実行して返されるN行のレコード 関連情報を取得するために、N回SELECT句を実行。 4 のパフォーマンスが悪くなったときに生じる問題。
問題の部分はさておいて、 「N+1」の現象を例から追ってみる 5
「N+1」の例 (テーブル) 6 author(著者) ID id 名前 name 生年月日 birthday
book(本) ID id 名前 name 著者ID author_id 言語ID language_id • 本テーブルが著者テーブルと言語テーブルとのリレーションを持つとする。 language(言語) ID id 名前 name
「N+1」の例 (レコード) 7 • 以下のようなレコードを持つとする book(本) id name author_id language_id
1 Javaの基礎 1 1 2 Goの基礎 1 1 language(言語) id name 1 日本語 author(著者) ID name birthday 1 山田太郎 1991/01/01
「N+1」の例 (求める結果) 8 • 本のIDをリクエストパラメータとして渡すと、以下のような結果をAPIから 返してほしい。 { “id”: “1”, “name”:
“Javaの基礎”, “author”: “山田太郎”, “言語”: “日本語” }
「N+1」の例 (処理) 9 • 以下のような処理を実行する。(ピンク色はレスポンスするパラメータ) 1. SELECT * FROM book
WHERE book.id = “1”;を実行する 2. {“id”: “1”, “name”:“Javaの基礎”, “author_id”: “1”, “language_id”: “1”}が返る。これを元にさらにSELECT句を実行する。 3. SELECT * FROM author WHERE author.id = 1;を実行する。 4. {“id”: “1”, “name”:“山田太郎”}が返る 5. SELECT * FROM language WHERE language.id = 1;を実行する。 6. {“id”: “1”, “name”:“日本語”}が返る このネスト構造のような取得方法が「N+1」という現象。
別にコレ自体が悪いわけではない。 では問題は? 10
問題としての「N+1」 11 テーブルA テーブルB テーブルC • 以下のようなデータ構造があったとして、A~Fのデータが必要で、「N+1」の方法で 取得するとする。すると最低でも合計5クエリ必要。 • 中間テーブルのレコード数が1つ増えるたびに、3テーブル分のクエリが追加され
る。 • このデータ構造からリスト形式の画面を作るとなると、テーブル B以降のクエリの多 さはテーブルAから読み取るレコードに比例して多くなる。 中間テーブルZ テーブルG テーブルH
こういった感じでクエリの数が爆発てきに増え、DBの 性能との兼ね合いで、ユーザーに不便が生じる程の パフォーマンスになる可能性がある。 12
では解決方法は? 13 • ORMによって具体的な解決方法は異なるらしいが、Djangoでは各テーブルを 結合してSELECTするための関数を使うことで、クエリの数を減らす対応が 考えられる。 • また、どのORMにも共通して言えることは素のSQLを書いてしまうことであ る。
まとめ • N+1とは、入れ子構造になったSELECT句の実行形式である。 • N+1となる事自体が問題ではなく、業務上悪いパフォーマンスになること が、N+1問題。 • 解決方法としてシンプルなのは、結合を用いたSQLをORMに書かせること、 または自分でSQLを書くこと。 14
参考文献 • Railsライブラリ紹介 : N+1問題を検出する「 bullet」 ◦ https://www.techscore.com/blog/2012/12/25/rails%E3%83%A9%E3%82%A4%E3% 83%96%E3%83%A9%E3%83%AA%E7%B4%B9%E4%BB%8B-n1%E5%95%8F%E9%A1%8C%E3%82% 92%E6%A4%9C%E5%87%BA%E3%81%99%E3%82%8B%E3%80%8Cbullet%E3%80%8D/
15