
๐น N+1 ์ด๋?
1๋ฒ ์ฟผ๋ฆฌ: ๋ถ๋ชจ ๋ชฉ๋ก ์กฐํ (1๋ฒ)
N๋ฒ ์ฟผ๋ฆฌ: ๊ฐ ๋ถ๋ชจ๋ง๋ค ์์ ์กฐํ (N๋ฒ)
โ ์ด N+1๋ฒ ์ฟผ๋ฆฌ ์คํ
๐ ๋ฌธ์ ์ ๋ณธ์ง
์ฟผ๋ฆฌ ๊ฐ์๊ฐ ๊ธฐํ๊ธ์์ ์ผ๋ก ๋์ด๋จ
์ฑ๋ฅ ์ ํ (ํนํ ๋คํธ์ํฌ, DB ๋ถํ)
ORM์ผ๋ก ์งํ ํ๋ฉด์ ๊ธฐ๋ณธ ์กฐํ ๋ฐฉ์์ Lazy Loading์ด๊ธฐ ๋๋ฌธ์ ORM๋ด์์
์ํฐํฐ ์ ์ ๋ฐ FK ๋ฑ์ ์ฐธ์กฐํด ์ต์ ์ ์ฟผ๋ฆฌ๋ฅผ ํ ํธ๋ ์ ์ ์ ๋ง๋ ๋ค.์ด๋, ๊ธฐ์ค ํ ์ด๋ธ ์กฐํ + ์์ ํ ์ด๋ธ ์กฐํ ๋๋ ํ๋ง๋ค ๋ชจ๋ ์ถ๊ฐ๋ก ์กฐํ ๋๋ค.
Order ์ Customer ๋ N:1 ๊ด๊ณ์ด๋ฉฐ,
ORM(Entity Framework) ๊ธฐ์ค์ผ๋ก Lazy Loading ์ด ๊ธฐ๋ณธ ๋์์ด๋ผ๊ณ ๊ฐ์
public class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; } // N:1 ๊ด๊ณ
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
}
๋ฌธ์ ๋ฐ์ ์ฝ๋ (N+1 ๋ฐ์ ์ง์ )
Order ๊ฐ์ฒด์์ Customer ์ ์ ๊ทผํ๋ ์๊ฐ,
Order ๊ฐ์ฒด์ Customer.Name ๋ฐ์ดํฐ๊ฐ ์์์ผ๋ก ORM์ด ํ๋จ
๊ฐ Order ๋ง๋ค Customer ์กฐํ ์ฟผ๋ฆฌ๋ฅผ ์ถ๊ฐ๋ก ์คํ
var orders = context.Orders.ToList(); // (1) ์ฃผ๋ฌธ ๋ชฉ๋ก ์กฐํ โ ์ฟผ๋ฆฌ 1๋ฒ
foreach (var o in orders)
{
Console.WriteLine(o.Customer.Name); // (2) ์ฃผ๋ฌธ ์(N)๋งํผ ์ฟผ๋ฆฌ ๋ฐ์
}
์ด๋ฌํ ๋ฌธ์ ๋ฅผ "N+1์ ์ค๋ฅ"๋ผ๊ณ ํ๋ฉฐ ORM์ ๊ฐ์ฒด์ฃผ์ ์ปจํ ์ค ๊ธฐ๋ฐ ํธ๋ ์ ์ ์๋ํ ์คํ ์ฆ, ์ํฐํฐ๊ธฐ๋ฐ ์ต์ ์ ์ฟผ๋ฆฌ๋ฅผ ์์ฑ ๋ฐ ์กฐํ ์ ๊ธฐ๋ณธ ์ ๋ต(Lazy Loading) ๋ฌธ์ ์ด๋ค.
ํด๊ฒฐ๋ฒ์ผ๋ก๋ ์กฐํ ๋ฐฉ์์ Include ๋ฅผ ์ ์ธํ๊ฑฐ๋ ํน์ ADO ํ์์ผ๋ก ์์ฑ์ ํ๋๊ฒ์ ๊ถ์ฅํ๊ณ ์๋ค.
N+1 ๋ฌธ์ ๋ ORM์์ ์ฐ๊ด ๊ด๊ณ๋ฅผ Lazy Loading ๋ฐฉ์์ผ๋ก ์กฐํํ ๋,
๋ถ๋ชจ ์กฐํ 1๋ฒ ์ดํ ์์ ์กฐํ๊ฐ N๋ฒ ์ถ๊ฐ๋ก ๋ฐ์ํ๋ ์ฑ๋ฅ ๋ฌธ์ ์ด๋ค.
ORM์ ๊ฐ์ฒด ์ค์ฌ ๊ฐ๋ฐ๊ณผ ํธ๋์ญ์
๊ด๋ฆฌ์ ๊ฐ์ ์ด ์์ง๋ง,
์กฐํ ์ ๋ต์ ์๋ชป ์ฌ์ฉํ๋ฉด N+1 ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๋ฐ๋ฉด ADO๋ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์์ฑํ๋ฏ๋ก JOIN์ ํตํ ๋จ์ผ ์กฐํ๊ฐ ๋ช
ํํด
N+1 ๋ฌธ์ ๊ฐ ๊ตฌ์กฐ์ ์ผ๋ก ์ ๋ค.
๐น ORM(Object Relational Mapping) ์ด๋?
๊ฐ๋ฐ์ ์ ์ฅ์์ ๊ฐ์ฒด ์ ๊ทผ
DB ์ ์ฅ์์ ํ๋์ ์ฟผ๋ฆฌ
order.Customer.Name
๐ ADO ๋ฐฉ์์ฒ๋ผ ๊ฐ๋ฐ์๊ฐ ํธ๋์ญ์ ์์๋ฅผ ํ๋ํ๋ ์ ๊ฒฝ ์ฐ์ง ์์๋ ๋๋ค.
๋ณด๋ค ๊ฐ๋ ฅํ ์ฌํญ์ CUD ์์ ๋ฐ์ํ๋ค
์ฌ๋ฌ ํ ์ด๋ธ์ ๊ฑธ์ณ ๊ด๊ณ๊ฐ ์๋ ๋ฐ์ดํฐ๋ฅผ Insert / Update / Delete ํ ๋ ORM ์ด ํนํ ๊ฐํ๋ค.
์ด์ ๋, ์ํฐํฐ ์ ์ธ์ ํตํด ์ด๋ฏธ ORM ํ ์ด๋ธ๊ฐ ์/ํ ๊ด๊ณ๋ฅผ ์ด๋ฏธ ์๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค
ํ์ง๋ง, ๋ฌธ์ ๋ ์กฐํ(Read)์ด๋ค.
๊ธฐ๋ณธ ์กฐํ ์ ๋ต์ด Lazy Loading ์ธ ๊ฒฝ์ฐ N+1 ๋ฌธ์ ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ๋ค.
Lazy Loading
EF(Entity Framwork)๋ Context ์์ ํด๋น DB๋ฅผ ๊ธฐ์ตํ๊ณ ์๋ค๊ฐ, ์ค์ ์ ๊ทผ์ ํ๋ ๊ฒ์ ํ์ธ ํ DB ์กฐํ๋ฅผ ์คํ.
๐น ADO(ADO.NET) ์ด๋?
ORM ์ ๊ฐ์ฒด ์ค์ฌ ๊ฐ๋ฐ๊ณผ ํธ๋์ญ์ ๊ด๋ฆฌ์ ๊ฐ์ ์ด ์๋ ๊ธฐ์ ์ด๊ณ
ORM ์ ํธ๋ฆฌํ์ง๋ง ์กฐํ ์ ๋ต์ ์๋ชป ์ฌ์ฉํ๋ฉด N+1 ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๊ณ ,
ADO ๋ ์ฟผ๋ฆฌ ์ค์ฌ์ผ๋ก ์ฑ๋ฅ๊ณผ ๋ช ํ์ฑ์ ํ๋ณดํ๋ ๋ฐฉ์์ด๋ค.
ADO ๋ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ์์ฑํ๋ ๋งํผ ๋ ๋ง์ ๊ณต์๊ฐ ๋ค์ง๋ง ๋์ฉ๋ ์กฐํ๋ ์ฑ๋ฅ ์ธก๋ฉด์์๋ ๋ ์์ ์ ์ธ ์ ํ์ด ๋ ์ ์๋ค.
ORM ์ ์์ฐ์ฑ์, ADO ๋ ์ ์ด๊ถ๊ณผ ์ฑ๋ฅ์ ์ ํํ๋ ๋ฐฉ์์ด๋ค.