# JPA 的 N+1 試煉之路 - Tim Chen
{%hackmd KzWJk9g7Sb6gDn9uM5aJKQ %}
## 現實生活中的 N+1
講者舉例:開會沒帶到報告要使用的文件,需要回去位子一趟
真的蠻像是 JPA Lazy Loading 在當下沒有取得需要的資料,在呼叫 getter 的時候才產生 SQL 並執行到資料庫中取值的行為一樣,這樣的行為一但多起來,就會影響整體的效能(增加執行時間。
## N+1 Query Problem 3W1H
### What is N+1 Query Problem
One query for parents and N queries for children.
### Why it decrease performance
The round trip to database is more expensive than query itself.
### When will it happen
Always happen on lazy loading.
有說明是『Always』應該是還有其他可以觸發的條件,但時間不夠所以沒有提及
### How to solve it
1. Aggregate perents' id and use for child talbe query.
- select * from parents ....
- select * from child ... where parent_id in (...)
2. JPA Fetch Join
3. Entity Graph
## Entity Graph
### purpose
提供更有彈性的 Fetch Strategy,因為 JPA Fetch Type 是 static 的,如果要更有彈性的切換 LAZY/EAGER 就可以考慮使用 Entity Graph,並且成為 Eager 的 related association 將會以 Join 的方式成為一句 SQL Query 被執行。
### advantage
ORM 的使用者大多不想要接觸太多資料庫細節的操作(像是撰寫 SQL,只想要把 Entity Relation Define 清楚(@OneToOne, @OneToMany...,剩下的 SQL 要如何下就交給 ORM Framework 處理。
使用 Entity Graph 比起自己使用 @Query(select * from ... fetch join ...)
相對的更貼近物件導向的使用方式,並沒有參雜過多的資料庫細節處理。
###### tags: `JCCONF22`