2025-01-21 09:56
【 後端陷阱: N+1 query 】
N+1 查詢問題通常發生在使用 ORM 進行資料庫操作時。
假設你有兩個關聯的實體,例如使用者和貼文。當你想獲取所有用戶及其對應的帖子時,我們需要
1. 查詢所有用户(1 )
2. 對於每個用戶,查詢其對應的貼文(N個用戶)
一般情況下,每一個查詢ORM都會轉換成SQL向數據庫查詢。如果用戶數量不大,當中的查詢不會對數據庫造成壓力。但隨著用戶增加,大量的數據庫查詢會減慢查詢效能,甚至令數據庫崩潰,這就是所謂的 N+1 query 問題。
要解決問題,我們不能每個用戶數據都發出一個請求。而最直觀的方法是利用 join table,之後可以用 for loop 存取數據。這個動作在ORM的世界叫作 eager loading,而不同的 ORM 都有對應的函數,例如 Django的 prefetch_related,Prisma 的 include。除外,我們也可以緩存數據來減輕問題。
N+1 問題雖然容易解決,卻因為ORM的便利常常被忽略,而在部署後才被發現。所以這也是我 review PR 的其中一個 checklist item。