# 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`