์ด ํฌ์คํ
์ ์์ ๋๋ฉ์ธ ๊ตฌ์กฐ ์ฐ์ํ๊ฒ ์ค๊ณํ๊ธฐ ๋ด์ฉ์ ์ด์ด์ ์์ฑ๋ฉ๋๋ค.
๋ชฉ์ฐจ
๋ฐฐ๊ฒฝ
์ง๋ ํฌ์คํ
์์๋ ์ํธ ๊ฐ์ฒด๊ฐ ์์กด๋๋ฅผ ๋ฎ์ถ๊ณ , ๋น์ฆ๋์ค ๋ก์ง์ ๋๋ฉ์ธ ๊ฐ์ฒด๋ก ๋ฃ์ด ์์ง๋๋ฅผ ๋์ด๋ ๋๋ฉ์ธ ์ฌ์ค๊ณ๋ฅผ ์งํํ๊ณ ์ ์ฉํด ๋ณด์์ต๋๋ค. ์ด๋ฌํ ๊ณผ์ ์์ ๋น์ฆ๋์ค ๋ก์ง์ด ์๋น์ค ๊ณ์ธต์ ๋ ํฌ์งํ ๋ฆฌ ๋ฉ์๋์์ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ด๋ถ๋ก ์ด๋ํ๊ฒ ๋์๊ณ , ๋๋ถ๋ถ์ ์ฟผ๋ฆฌ๋ฅผ JPA ๊ธฐ๋ฅ์ ๋งก๊ธฐ๊ฒ ๋์์ต๋๋ค. ์ด๋ก ์ธํด ๊ณผ๊ฑฐ์ ์ฟผ๋ฆฌ ํ๋์ ์งํํ๋ ์ฟผ๋ฆฌ๋ค์ด ์ฌ๋ผ์ง๊ฒ ๋์๊ณ , JPA ๊ฐ ์๋์ผ๋ก ๋ง๋ค์ด์ฃผ๋ ์๋ก์ด ์ฟผ๋ฆฌ์ ์ฑ๋ฅ์ ํ์ธํด๋ณด๊ณ ์ ํ์์ต๋๋ค.
ํ ์คํธ ํ๊ฒฝ
ํ
์คํธํ ๋๋ฉ์ธ์ ์ฌ์ค๊ณ๋ฅผ ์งํํ๋ ํฌํ ๋๋ฉ์ธ์ผ๋ก ํ
์คํธ๋ฅผ ์งํํ์๊ณ , ๋๋ฏธ ๋ฐ์ดํฐ๋ ์ฟผ๋ฆฌ ํ๋์ ํ๋ ๋์ ๊ฐ์ ์๋ก ๋ฃ์ด์ฃผ์์ต๋๋ค.
โข
๋ฉค๋ฒ: 500
โข
ํ: 1000
โข
ํ ๋ฉค๋ฒ: 2996
โฆ
1๋ฒ ๋ฉค๋ฒ๋ ํ
์คํธ ํธ์์ ๋ชจ๋ ํ์ ์ฐธ์ฌ, ์ด์ธ 499๋ช
์ ๋ฉค๋ฒ๋ 4๊ฐ์ ํ์ ์ฐธ์ฌ
โข
ํฌํ: 30000
โฆ
๊ฐ ํ๋น 30๊ฐ์ ํฌํ ์์ฑ
โข
ํฌํ ํญ๋ชฉ: 90000
โฆ
ํฌํ๋น 3๊ฐ์ ํฌํ ํญ๋ชฉ
โข
์ ํ ์ธ์: 180000
โฆ
ํฌํ ํญ๋ชฉ๋น 2๋ช
ํฌํ
์ฑ๋ฅ ๊ฐ์ ์ด ํ์ํ ๋ถ๋ถ
ํฌํ ๊ธฐ๋ฅ์ ๋ชจ๋ API ์ ๋ํด์ ๋ถํ์ํ ์ฟผ๋ฆฌ๋ JOIN๋ฌธ์ด ์๋์ง ์ฑ๋ฅ ํ
์คํธ๋ก ํ์ธํด ๋ณด์์ต๋๋ค.
[ํฌํ ์ฑ๋ฅ ํ
์คํธ]
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 4148.619320 ms, ์ฟผ๋ฆฌ ๊ฐ์: 124, ์ฟผ๋ฆฌ ์๊ฐ: 2123.705562 ms
uri: '/api/groups/00000002/polls', method: 'POST', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 476.378221 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 14.347752 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 279.455596 ms, ์ฟผ๋ฆฌ ๊ฐ์: 7, ์ฟผ๋ฆฌ ์๊ฐ: 238.463966 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/items', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 1295.610065 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 1235.628151 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 153.095624 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 4.681824 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 28.595276 ms, ์ฟผ๋ฆฌ ๊ฐ์: 8, ์ฟผ๋ฆฌ ์๊ฐ: 4.014231 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 92.646055 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 6.505827 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/result', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 68.598734 ms, ์ฟผ๋ฆฌ ๊ฐ์: 8, ์ฟผ๋ฆฌ ์๊ฐ: 2.851347 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/close', method: 'PATCH', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 39.222127 ms, ์ฟผ๋ฆฌ ๊ฐ์: 5, ์ฟผ๋ฆฌ ์๊ฐ: 1.428766 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'DELETE', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 173.856499 ms, ์ฟผ๋ฆฌ ๊ฐ์: 10, ์ฟผ๋ฆฌ ์๊ฐ: 136.763482 ms
Shell
๋ณต์ฌ
fetch join ์ ์ฌ์ฉํ์ง ์์๊ธฐ์, N+1 ์ ์์์ ํ์ง๋ง ์ฒซ API์ธ ํฌํ ๋ชฉ๋ก ์กฐํ API๋ถํฐ ๋ง๋๋๊น ์์ธํ ๊ธฐ๋ถ์ด ๋ค์์ต๋๋ค. ๊ฒ๋ค๊ฐ 124๊ฐ ์ฟผ๋ฆฌ์ ๊ฐ์๋ฅผ ๋ณด์ํ๋ ๋จ์ํ N+1 ์ ๋ฌธ์ ๊ฐ ์๋์์ต๋๋ค.
ํ์ฌ ํ
์ด๋ธ์ ์ฐ๊ด ๊ด๊ณ๋ ์์ ERD ์์ ํ์ธํ ์ ์๋ฏ์ด, ํฌํ - ํฌํ ํญ๋ชฉ - ์ ํ์ธ์์ผ๋ก ์ด์ด์ง๋ 1:N:N^2 ์ ๊ด๊ณ์
๋๋ค.
@Query("select p from Poll p where p.menu.teamCode.code = :teamCode")
List<Poll> findAllByTeamCode(@Param("teamCode") String teamCode);
Java
๋ณต์ฌ
List<Poll> ์คํธ๋ฆผ์ ๋๋ฉด์ poll.getPollItems() ์ ํธ์ถํ๊ณ , ๋ฐํ๋ List<PollItem> ์์ ์คํธ๋ฆผ์ ๋๋ฉด์ pollItem.getSelectMembers().keySet() ์ ํธ์ถํ๋ ๋ก์ง์
๋๋ค. ์ด์ ๋ฐ๋ผ poll ์์ poll item ์ ๋ถ๋ฌ์ฌ ๋ N + 1, poll item ์์ select member ๋ฅผ ๋ถ๋ฌ์ฌ ๋ N + 1 ์ด ๋ฐ์ํ๋ ๋ก์ง์ด์์ต๋๋ค. ์ด๋ฅผ ์์์ผ๋ก ํํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
N ์ ํฌํ ๋ฐ์ดํฐ์ ๊ฐ์, M ์ ํฌํ ํญ๋ชฉ ๋ฐ์ดํฐ์ ๊ฐ์์
๋๋ค. ๊ณ์ฐ์ ํ๋ฉด, 30 * 3 + 30 + 1 ์ ๊ธฐ๋ณธ ๊ฒ์ฆ ๋ก์ง ์ฟผ๋ฆฌ 3๊ฐ(๋ฉค๋ฒ ์กฐํ, ํ ์กฐํ, ๋ฉค๋ฒ ํ ์์ ํ์ธ)๋ฅผ ํฉ์ณ ์ด 124๊ฐ๊ฐ ๋ฐ์ํ ๊ฒ์
๋๋ค. ์ฐจ๋ผ๋ฆฌ ํ
์คํธ์์ ์ฟผ๋ฆฌ ๊ฐ์๋ฅผ ์๋ชป ์ธ๊ธฐ๋ฅผ ๋ฐ๋ฌ์ง๋ง, ๋ถํ์ํ๊ฒ ์ ํํ ๊ณ์ฐ์ ํด๋ฒ๋ ธ์ต๋๋ค.
Fetch Join ์ฌ์ฉ
์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด์, ๋ณดํธ์ ์ผ๋ก N + 1 ์ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ธ fetch join ์ ๊ฐ์ฅ ๋จผ์ ์ ์ฉํด ๋ณด์์ต๋๋ค.
ํฌํ๋ฅผ ๋ถ๋ฌ์ฌ ๋ ์ฐ๊ด ๊ด๊ณ๋ฅผ ๋งบ๊ณ ์๋ ํฌํ ํญ๋ชฉ์ join fetch๋ก ๋ถ๋ฌ์ค๋ฉด JOIN์ ์ด์ฉํ ํ๋์ ์ฟผ๋ฆฌ๋ก ํฌํ์ ํฌํ ํญ๋ชฉ์ ๋ถ๋ฌ์ฌ ์ ์๊ณ , ์ด ๋ ํฌํ ํญ๋ชฉ์ ๋ถ๋ฌ์ค๋ฉด์ ์ ํ ์ธ์๋ ํจ๊ป JOIN์ ์ด์ฉํ ์ฟผ๋ฆฌ๋ก ๋ถ๋ฌ์ค๋๋ก ํ์์ต๋๋ค.
@Query("select p "
+ "from Poll p "
+ "join fetch p.pollItems.values pi "
+ "join fetch pi.selectMembers "
+ "where p.menu.teamCode.code = :teamCode")
List<Poll> findAllByTeamCode(@Param("teamCode") String teamCode);
Java
๋ณต์ฌ
์ฟผ๋ฆฌ์ ๊ฒฐ๊ณผ์ ์ฑ๋ฅ์ ์ดํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
์์ ์ฟผ๋ฆฌ์ฒ๋ผ inner join ์ ๋ ๋ฒ ๊ฑธ์ด poll ์์ select member ๊น์ง ๋ ์ธ๋์ ๊ฑธ์น ๋ฐ์ดํฐ๋ฅผ ํ๋ฒ์ ๊ฐ์ ธ์ต๋๋ค.
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 3009.070515 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 1097.437801 ms
Java
๋ณต์ฌ
์ฑ๋ฅ์ ๋ณด๋ฉด ์ฟผ๋ฆฌ ์๊ฐ์ด ์ฝ 50% ๊ฐ๋ ๊ฐ์ ๋ ๊ฒ์ ์ ์ ์๊ณ , ์ฟผ๋ฆฌ ๊ฐ์๋ ํด๊ฒฐํ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
ํ์ง๋ง ๋ ํ
์ด๋ธ ๋ชจ๋ inner join ์ผ๋ก ์กฐํํ๋ฉด ์๋น์ค ์ ์ฑ
์ ๋ฌธ์ ๊ฐ ๋ฐ์ํฉ๋๋ค. ํฌํ๋ฅผ ์์ฑํ ๋์๋ ํฌํ ํญ๋ชฉ์ ํ์ ์ด์ง๋ง, ์๋ฌด๋ ํฌํ๋ฅผ ํ์ง ์์๋ค๋ฉด ํฌํ ํญ๋ชฉ์ ๋ํ ์ ํ ์ธ์์ ์์ ๋๊ฐ ์์ต๋๋ค. ํฌํ๋ฅผ ์ฒ์ ์์ฑํ์ ๋์ฒ๋ผ ๋ง์ด์ฃ . ์ด๋ ๊ฒ ๋๋ค๋ฉด ๋ ๋ฒ์งธ inner join ์ธ select member JOIN ๋ฌธ์์ ์ฐ๊ด๋ ๋ฐ์ดํฐ๊ฐ ์๊ธฐ๋๋ฌธ์ ํฌํ๋ ์กด์ฌํ๋๋ฐ ์๋ฌด ๋ฐ์ดํฐ๋ ๊ฐ์ ธ์ค์ง ๋ชปํ๋ ์ํฉ์ด ๋ฐ์ํฉ๋๋ค.
๊ทธ๋์ ๋ ๋ฒ์งธ JOIN ๋ฌธ์ธ inner join ์ left outer join ์ผ๋ก ๋ฐ๊พธ์ด, ํฌํ๊ฐ ์์ง ์งํ๋์ง ์์๋๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋๋ก ํ์์ต๋๋ค.
@Query("select p "
+ "from Poll p "
+ "join fetch p.pollItems.values pi "
+ "left join fetch pi.selectMembers "
+ "where p.menu.teamCode.code = :teamCode")
List<Poll> findAllByTeamCode(@Param("teamCode") String teamCode);
Java
๋ณต์ฌ
select member ํ
์ด๋ธ์ left outer join ์ผ๋ก ๋ฐ๊พธ๊ณ ๋ค์ ํ
์คํธ๋ฅผ ๋๋ ค ๋ณด๋ฉด,
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 3127.241793 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 2025.988033 ms
Java
๋ณต์ฌ
์ฟผ๋ฆฌ ๊ฐ์๋ ๋์ผํ์ง๋ง inner join ๋์ left outer join ์ ํ๊ฒ ๋์ด ์ฟผ๋ฆฌ ์ฒ๋ฆฌํ๋ ์๊ฐ์ด ์๋ฌด๋๋ ๋ ์ค๋ ๊ฑธ๋ฆด ์ ๋ฐ์ ์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์๊ฐ ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ์น๋ช
์ ์ธ ๋ฌธ์ ๋ ๋ฐ์ํ์์ต๋๋ค.
ํฌํ ๋๋ฏธ ๋ฐ์ดํฐ๋ 30๊ฐ์ธ๋ฐ, ์ฐ๊ด๋ ํฌํ ํญ๋ชฉ์ธ 3๊ฐ๊น์ง ๊ฐ์ ธ์ค๋ค๋ณด๋ ํฌํ์ ๋ํ ๋ฐ์ดํฐ๊ฐ 90๊ฐ๊ฐ ๋์์ต๋๋ค. ์ฆ ์ค๋ณต๋ ํฌํ๊ฐ 3๊ฐ์ฉ ์๊ธด ๊ฒ์
๋๋ค. ์ฌ๊ธฐ์ ๋ง์ฝ ์ ํ ์ธ์์ด ์๋ค๋ฉด, ๊ทธ ์ ํ ์ธ์ ๋ฐ์ดํฐ๋งํผ ๋ ์ค๋ณต๋ ํฌํ ๊ฐ์ฒด๊ฐ ์๊ธฐ๊ฒ ๋ฉ๋๋ค. ์ด์ ๋ฐ๋ผ ํฌํ์ ๋ํด distinct ์ต์
์ ์ฌ์ฉํ๊ธฐ๋ก ํ์์ต๋๋ค.
@Query("select distinct p "
+ "from Poll p "
+ "join fetch p.pollItems.values pi "
+ "left join fetch pi.selectMembers "
+ "where p.menu.teamCode.code = :teamCode")
List<Poll> findAllByTeamCode(@Param("teamCode") String teamCode);
Java
๋ณต์ฌ
์ค๋ณต์ผ๋ก ์กด์ฌํ๋ ํฌํ ๊ฐ์ฒด๋ฅผ distinct ๋ก ์ ๊ฑฐํ์ฌ ๋ฐ์ดํฐ๊ฐ ์ ํํ๊ฒ ๊ณ์ฐ๋ ๊ฒ์ ํ์ธํ ์ ์์์ต๋๋ค.
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 1394.154046 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 638.585152 ms
Java
๋ณต์ฌ
ํ์ง๋ง ์ด๋ฌํ @OneToMany ์์ join ์ ๊ฑฐ๋ ๋ฐฉ์์ ๊ณ ์ง์ ์ธ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์๋ฌด๋ฆฌ ์ ํ๋ฆฌ์ผ์ด์
๋จ์์ ์ค๋ณต๋ ๊ฐ์ฒด์ ๋ํด distinct ๋ฅผ ์ ์ฉํ๋ค์ง๋ง ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ๋์๋ ๊ฒฐ๊ตญ ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ ์ ๋ฐ์ ์์ต๋๋ค.
DB ์์ ์กฐํํ ๋์๋ ๊ฒฐ๊ตญ ์ค๋ณต๋ ๋ฐ์ดํฐ๊ฐ ์กด์ฌํ๊ณ , ๊ฐ์ฒด๋ก ๋งคํ ์์ ์ค๋ณต๋ ๋ฐ์ดํฐ๋ฅผ distinct ํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์ดํ๋ฆฌ์ผ์ด์
์ ๋ถํ์ํ ๋ถํ๊ฐ ๋ฐ์ํ ์ ๋ฐ์ ์๊ธฐ์, ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฐพ์๋ณด๊ฒ ๋์์ต๋๋ค.
BatchSize ์ค์
๋ชฉ๋ก์ ์กฐํํ๋ ๋น์ฆ๋์ค ๋ก์ง์ ์คํธ๋ฆผ์ ๋๋ฉด์ ํ๋์ฉ ๊บผ๋ด๊ธฐ ๋ณด๋ค๋ ํ๋ฒ์ ๋ชจ๋ ๊ฐ์ฒด๋ฅผ ๋ฒํฌ ์ฐ์ฐ์ผ๋ก ์กฐํํ๋ ๋ฐฉ์์ผ๋ก ์๊ฐํด ๋ณด์์ต๋๋ค. ์ด๋ BatchSize ์ต์
์ ํตํด
1.
team_code ๋ก ํฌํ ์กฐํํ๊ธฐ
2.
์กฐํํ poll_id ๋ค๋ก ํฌํ ํญ๋ชฉ ์กฐํํ๊ธฐ
3.
์กฐํํ poll_item_id ๋ค๋ก ์ ํ ์ธ์ ์กฐํํ๊ธฐ
๋ฑ 1 + 1 + 1 ์ฟผ๋ฆฌ๋ก ํด๊ฒฐํ๊ธฐ๋ก ํ์์ต๋๋ค. BatchSize๋ฅผ ์ ์ฉํ๋ฉด ์กฐํ ์ฟผ๋ฆฌ์์ in ์ ์ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ์ค์ ํ ๊ฐ์๊น์ง๋ ํ๋์ ์ฟผ๋ฆฌ๋ง์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
spring:
jpa:
properties:
hibernate:
default_batch_fetch_size: 100
YAML
๋ณต์ฌ
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 3468.259955 ms, ์ฟผ๋ฆฌ ๊ฐ์: 10, ์ฟผ๋ฆฌ ์๊ฐ: 1100.283345 ms
Java
๋ณต์ฌ
in (?) ์ผ๋ก ๊ฐ์ ธ์ฌ ๋, ํฌํ ํญ๋ชฉ์ ๊ฐ์ ธ์ฌ ๋์๋ ํฌํ ๊ฐ์๊ฐ 30๊ฐ์ด๊ณ , ์ ํ ์ธ์์ ๊ฐ์ ธ์ฌ ๋์๋ ํฌํ ํญ๋ชฉ์ด 3 * 30 ์ด 90๊ฐ์ด๊ธฐ๋๋ฌธ์ default_batch_fetch_size ๋ฅผ 100 ์ผ๋ก ์ค์ ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด ๋ณด์์ต๋๋ค. ์์ํ ๊ฒฐ๊ณผ๋ ๊ธฐ๋ณธ ๊ฒ์ฆ ๋ก์ง 3๊ฐ๊น์ง ํฉ์ณ ์ด 6๊ฐ์ ์ฟผ๋ฆฌ ๊ฐ์๊ฐ ๋ฐ์ํ ๊ฒ์ผ๋ก ์์ํ์๋๋ฐ, 10๊ฐ๊ฐ ๋ฐ์ํ์์ต๋๋ค. ํฌ๋ํฐ ๊ณ ๋ฏผ์ ์๊ณ ์ฝ์๋ก ์ฟผ๋ฆฌ๋ฅผ ํ์ธํด๋ณด๋ ๋ค์๊ณผ ๊ฐ์์ต๋๋ค.
์ ์ฟผ๋ฆฌ๋ ? * 30 ์ ์์ํ์์ง๋ง, ? * 25, ? * 5 ๋ ๊ฐ๋ก ๋ง๋ค์ด์ก์ต๋๋ค. ์์ํ๋ 1 + 1 + 1 ์ผ๋ก ์ฟผ๋ฆฌ๊ฐ ๋ง๋ค์ด์ง์ง ์๊ณ ์ชผ๊ฐ์ ธ์ ์ฟผ๋ฆฌ๊ฐ ๋ง๋ค์ด์ง ๊ฒ์
๋๋ค. ์ฟผ๋ฆฌ ๊ฐ์๊ฐ ์ด 10๊ฐ๊ฐ ๋ฐ์ํ ๊ณผ์ ์ ์๊ฒ ๋์๊ณ , ์ด๋ ๊ฒ ๋๋ ์์ธ์ ์ฐพ์๋ณด๊ธฐ๋ก ํ์์ต๋๋ค.
์ด์ ๊ดํด์ batch size ๋ฅผ ์ด์ฉํ ๋์ prepared statement ์์๋ (?) ์ ๊ฐ์๋ฅผ ๋ฏธ๋ฆฌ ์ ํด๋๊ณ , ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ์บ์ฑ์ ์ฌ์ฉํ๋ค๊ณ ํฉ๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ ์ฌ์ฉํ๋ ์ด์ ๋, ๋ช ๊ฐ์ (?) ๋ฅผ ํด์ผํ ์ง ๋ชจ๋ฅด๋ ์ํฉ์์ (?) ์ ๊ฐฏ์๋งํผ ๋์ ์ผ๋ก ๊ณ์ ๋ง๋ค๋ค๋ณด๋ฉด ์ฑ๋ฅ์ ๋ถ๋ฆฌํ๊ธฐ ๋๋ฌธ์
๋๋ค. ๊ทธ๋์ default_batch_fetch_size ์ ๊ฐ์๊ฐ 100 ์ด๋ผ๋ฉด, (?) ๊ฐ์๊ฐ 1~10, 100, 50, 25, 12 ์ด๋ ๊ฒ 14๊ฐ์ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ์บ์ฑํ์ฌ ์ฌ์ฉํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ ์์์์์ฒ๋ผ in (?) ์ ๋ก ๊ฐ์ ธ์์ผ ํ ๋ฐ์ดํฐ๊ฐ 30๊ฐ๋ผ๋ฉด ? * 25 ์ธ๊ฑฐ ํ๋, ? * 5 ์ธ๊ฑฐ ํ๋ ์ด 2๊ฐ์ ์ฟผ๋ฆฌ๊ฐ ๋ฐ์ํ๊ฒ ๋ ๊ฒ์
๋๋ค. default_batch_fetch_size ๋ก ์ค์ ํ ์๊ฐ ์๋ฌด๋ฆฌ ๋์๋, /2 ๋ฅผ ๊ณ์ํ๊ธฐ๋๋ฌธ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๋ in (?) ์ ์ ๊ฐ์๋ log N ๋งํผ ์ฆ๊ฐํฉ๋๋ค. ๊ทธ๋ ๋ค๋ฉด ์ด ๋ฐฉ์ ๋ง๊ณ ๋ค๋ฅธ ๋ฐฉ์์ ์ด๋ค๊ฒ ๋ ์์๊น์?
spring:
jpa:
properties:
hibernate:
batch_fetch_style: padded
YAML
๋ณต์ฌ
batch_fetch_style ์๋ legacy, padded, dynamic ์ด ์๊ณ , ์์ ์ธ๊ธํ ๋ฐฉ์์ด ๊ธฐ๋ณธ๊ฐ์ธ legacy ์
๋๋ค. dynamic ๋ฐฉ์์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํ ์บ์ฑ, ์ฆ ๋ฏธ๋ฆฌ ์ฟผ๋ฆฌ๋ฅผ ๋ง๋ค์ง ์๊ณ ๊ทธ๋ฅ ๋์ ์ผ๋ก ๋ง๋๋ ๋ฐฉ์์
๋๋ค. ์ ํฌ๊ฐ ์ค์ ํ padded ๋ legacy ์ ์ ์ฌํฉ๋๋ค. ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ํด ์ฟผ๋ฆฌ๋ฅผ ์บ์ฑํ๋ ๊ฒ ๊น์ง๋ ๊ฐ์ผ๋ legacy ๋ ๋ฐ์ดํฐ๋ณด๋ค ์ ์ ์์ (?) ๋ฅผ ์ฌ์ฉํ๋ ๋ฐ๋ฉด, padded ๋ ๋ฐ์ดํฐ๋ณด๋ค ๋ง์ ์์ (?) ๋ฅผ ์ฌ์ฉํฉ๋๋ค. ์์ ์์์ฒ๋ผ ๋ฐ์ดํฐ๊ฐ 30๊ฐ๋ผ๋ฉด ? * 50 ์ธ ์ฟผ๋ฆฌ๋ฅผ ๊ฐ์ ธ์์ ์ฌ์ฉํฉ๋๋ค.
๊ทธ๋ ๋ค๋ฉด ๋จ๋ ?*20๊ฐ์๋ ์ด๋ค ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ธ๋ฉํ ๊น์?
in (?) ์ ๋ก ๊ฐ์ ธ์ฌ ๋ฐ์ดํฐ์ ๋ฐ์ธ๋ฉ ํ๋ผ๋ฏธํฐ์ธ poll_id ๋ 31~60 ๊น์ง์์ต๋๋ค. ๊ทธ๋์ ๋๋จธ์ง 20๊ฐ์๋ ์ฒซ ๋ฐ์ดํฐ์ธ 31์ ๋๋ฏธ๋ก 20๋ฅผ ๋ฃ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค. ์ด๋ ๊ฒ ๊ฐ์ ธ์จ 20๊ฐ์ ๋ฐ์ดํฐ๋ distinct ์ ์ ์ฌํ ๋ก์ง์ผ๋ก ๊ฐ์ ๊ฐ์ฒด๋ก ์ธ์ํ์ฌ ๊ตฌ๋ถํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
WARN uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 2671.510999 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 733.745199 ms
Java
๋ณต์ฌ
์ ํฌ ํ๋ก์ ํธ์์๋ ์๋น์ค ํน์ฑ์ in (?) ์ ์ ๋ค์ด๊ฐ ๋ฐ์ดํฐ์ ๊ฐ์๊ฐ ์์ฃผ ๋ณํ๊ธฐ๋๋ฌธ์ dynamic ๋ณด๋ค๋ padded ๋ฅผ ์ด์ฉํ๊ธฐ๋ก ํ์์ต๋๋ค.
๋์ ํฉ์ณ๋ณผ๊น?
WARN uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 2798.888614 ms, ์ฟผ๋ฆฌ ๊ฐ์: 5, ์ฟผ๋ฆฌ ์๊ฐ: 1208.678814 ms
Java
๋ณต์ฌ
poll item ๊น์ง๋ join fetch ๋ก ๊ฐ์ ธ์ค๊ณ , ์ ํ ์ธ์์ in (?) ์ ๋ก ๊ฐ์ ธ์ค๋๋ก ํด๋ณด์์ต๋๋ค. ํ์ง๋ง ๊ฒฐ๊ตญ join ๋ฌธ์์ ๋ฐ์ํ๋ ๋น์ฉ์ด ๋ ํฌ๋ค๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค.
๋ฐ์ ๊ทํ๋ก ์กฐํ ์ฟผ๋ฆฌ ์ฑ๋ฅ ๊ฐ์
๋ชจ๋ in (?) ์ ๋ก ์ฒ๋ฆฌํ๋ 1 + 1 + 1 ์ฟผ๋ฆฌ๊ฐ ๊ฐ์ฅ ์ฑ๋ฅ์ด ์ข์์ง๋ง, 733 ms ๋ ์๋ฌด๋๋ ์ฌ์ฉ์๊ฐ ๋ต๋ตํจ์ ๋๋ผ๊ธฐ์๋ ์ถฉ๋ถํ ์๊ฐ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋์ ์ด๋ฅผ ์๋น์ค ๋ก์ง์ผ๋ก ๊ฐ์ ํ ์ ์๋ ๋ฐฉ๋ฒ๋ค์ ์๊ฐํด ๋ณด์์ต๋๋ค.
ํ์ด์ง์ผ๋ก ์ฒ๋ฆฌ
ํ์ฌ ์ ํฌ ํ๋ก์ ํธ์์๋ ํฌํ, ์ฝ์์ก๊ธฐ ๋ฑ์ ๊ธฐ๋ฅ๋ค์ ๋ชฉ๋ก์ ๋ถ๋ฌ์ฌ ๋์๋ ํ์ด์ง ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๊ณ ํ๋ฒ์ ๋ชจ๋ ๋ชฉ๋ก์ ๊ฐ์ ธ์ต๋๋ค. ์ด์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ค๋ณด๋, ์ค๋ ๊ฑธ๋ฆฐ๋ค๊ณ ํ๋จํ์ฌ ํ์ด์ง์ ํ๋ ๊ฒ์ ๋ํด ์๊ฐํด ๋ณด์์ต๋๋ค. ํ์ง๋ง ์ด๋ ๋ฐฑ์๋ ํ์๋ค ๋ฟ๋ง ์๋๋ผ ํ๋ก ํธ์๋ ํ์๋ค๊ณผ๋ ์๊ฒฌ์ ๋๋๊ณ , ํ๋ฉด ๋์์ธ๊ณผ ์ธ๋ถ ์ฌํญ๊น์ง ์ ํด์ผ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ฌด์๋ณด๋ค๋ ํฌํ, ์ฝ์์ก๊ธฐ ๋ฑ์ ์๋ณด๋ค๋ ํฌํ ํญ๋ชฉ, ์ ํ ์ธ์ ๋ฑ ํ๋ฒ์ ๊ฐ์ ธ์ค๋ ๊ตฌ์กฐ์์ ๋ฌธ์ ๋ผ๊ณ ์๊ฐํ์ฌ ์ผ๋จ ๋ณด๋ฅํ์์ต๋๋ค.
์ ๊ทํ์ ์ง์ฐฉํ์ง ๋ง์!
๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์๊ฐํด๋ณด๋ค๊ฐ ํฌํ ๋ชฉ๋ก์ ์กฐํํ๋ ๋ฐ์ ์ด์ฉ๋ค๊ฐ ๋ชจ๋ ์ ํ ์ธ์๊น์ง ๊ฐ์ ธ์ค๊ฒ ๋์์๊น ๋ผ๋ ์๋ฌธ์ด ์๊ฒผ์ต๋๋ค.
๋ชจ๋ ์ ํ ์ธ์๊น์ง ๊ฐ์ ธ์ค๊ฒ ๋ ์ด์ ๋ ํฌํ ์งํ ์ธ์์ ์ธ๊ธฐ ์ํด์ ์์ต๋๋ค. ํฌํ ๋ชฉ๋ก ์กฐํ ๋ก์ง์์ ํฌํ๋ฅผ ์งํํ ์ฌ๋์ ์(count)๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด, ํฌํ ์ ํ ํญ๋ชฉ๊ณผ ์ ํ ์ธ์์ ์ ๋ณด๊น์ง ๋ชจ๋ ์กฐํํด์ค๊ณ ์์์ต๋๋ค. ๊ฒฐ๊ตญ ํฌํ ๋ชฉ๋ก ์กฐํ ์, ํฌํ ํญ๋ชฉ์ ์กฐํํ๋ ์ด์ ๋ ์ ํ ์ธ์์ ์กฐํํ๊ธฐ ์ํด, ์ ํ ์ธ์์ ์กฐํํ๋ ์ด์ ๋ ํฌํ๋ฅผ ์งํํ ์ฌ๋์ ์๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด์ ์
๋๋ค. ์ด๋ฌํ ๋ฌธ์ ์ ์ ํ์
ํ ๋ค, ๊ตณ์ด ํฌํ ํญ๋ชฉ, ์ ํ ์ธ์ ๋ฑ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ํ์๊ฐ ์๋ค๊ณ ์๊ฐํ์์ต๋๋ค.
์ด์ ๋ฐ๋ผ ํฌํ ํ
์ด๋ธ์ count ๋ผ๋ ์ปฌ๋ผ์ ์ถ๊ฐํ๊ณ , ๋ฉค๋ฒ๊ฐ ํฌํ๋ฅผ ์งํํ๋ฉด count ๋ฅผ ์ฌ๋ฆฌ๋ ๋ก์ง์ ๋ง๋ค๊ธฐ๋ก ํ์์ต๋๋ค.
ํฌํ์ count ๋ ์ฐ๊ด ๊ด๊ณ์ ์๋ ์ ํ ์ธ์์ ์๋ฅผ ๊ณ์ฐํ ๊ฐ๊ณผ ์ผ์นํ๊ธฐ๋๋ฌธ์, ์ ๋ณด์ ์ค๋ณต๋๋ค๊ณ ๋ณผ ์ ์์ต๋๋ค. ํ์ง๋ง ์๋น์ค๋ฅผ ์ด์ฉํ๋ ์ฌ์ฉ์์ ๊ฒฝํ์ ์ค์ ์ ๋ ๋, ์กฐํ ์ฑ๋ฅ์ ๋ถ๋ด์ด ๋๋ ๊ฒ๋ณด๋ค๋, ์ ๊ทํ๋ฅผ ์กฐ๊ธ ํฌ๊ธฐํ๊ณ ์กฐํ ์ฑ๋ฅ์ ๋์ด๋ ๊ฒ์ด ์ ์ ํ๋ค๊ณ ์๊ฐํ์ฌ ๋ฐ์ ๊ทํ๋ฅผ ํ๊ธฐ๋ก ๊ฒฐ์ ํ์์ต๋๋ค.
public void doPoll(Long memberId, Map<Long, String> data) {
validateStatusOpen();
pollItems.doPoll(memberId, data);
this.selectedCount = updateSelectedCount();
}
Java
๋ณต์ฌ
pollItems.doPoll() ์์๋ ํฌํ๋ฅผ ์งํํ๊ณ , updateSelectedCount() ์์๋ ํฌํ๋ฅผ ์งํํ ์ธ์์ด ์ฌ์ ํํ ์ธ์์ธ์ง ์ฒ์ ํฌํํ๋ ์ธ์์ธ์ง ํ์ธํ ๋ค ์ฒ์ ํฌํํ๋ ์ธ์์ด๋ผ๋ฉด selectedCount ๋ฅผ 1 ์ถ๊ฐํฉ๋๋ค.์ดํ ์ปค๋ฐ ์์ ์ JPA ๋ dirty checking ์ ํตํด count ๋ฅผ update ํ๋ ์ฟผ๋ฆฌ๋ฅผ ๋ ๋ฆฝ๋๋ค. ๊ทธ๋ฆฌ๊ณ ํฌํ ๋ชฉ๋ก์ ์กฐํํ ๋๋, ๋จ์ํ Poll ํ
์ด๋ธ์ ์ ์ฅ๋ column ์ค ํ๋์ด๊ธฐ๋๋ฌธ์ ๋ค๋ฅธ ๋ก์ง ์์ด count ์กฐํ๊ฐ ๊ฐ๋ฅํฉ๋๋ค.
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 130.732916 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 15.434725 ms
YAML
๋ณต์ฌ
์์ฒญ ์ฒ๋ฆฌ ์๊ฐ, ์ฟผ๋ฆฌ ๊ฐ์, ์ฟผ๋ฆฌ ์๊ฐ ๋ฑ ๋ชจ๋ ์งํ์์ ์ ๋ช
ํ๊ฒ ์ฑ๋ฅ์ด ๊ฐ์ ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.
๋จ์ ์?
๊ทธ๋ ๋ค๋ฉด ์ด๋ฌํ ๋ฐ์ ๊ทํ๋ฅผ ์งํํ์ ๋ ์ด๋ค ๋จ์ ์ด ์์๊น์?
์ถ๊ฐ update ๋ก์ง
์์ ์ธ๊ธํ๋๋ก, ์๋ก์ด ๋ฉค๋ฒ๊ฐ ํฌํ๋ฅผ ์งํํ๋ฉด count ์๊ฐ ๋ณ๊ฒฝ๋์ด, ์ ํ ์ธ์ insert ์ฟผ๋ฆฌ์ ํจ๊ป ํฌํ update ์ฟผ๋ฆฌ๊ฐ ์ถ๊ฐ๋ก ๋ฐ์ํฉ๋๋ค.
ํ์ง๋ง ์๋น์ค ๋ก์ง ์ ์ฌํฌํ๋ ์์ง๋ง, ํฌํ ์ทจ์๋ผ๋ ๊ฐ๋
์ ์๊ธฐ์ update ์ฟผ๋ฆฌ๊ฐ ์์ฃผ ๋ฐ์ํ์ง ์์ ๊ฒ์ด๋ผ ํ๋จํ๊ณ , ๋ฌด์๋ณด๋ค๋ ํฌํ, ํฌํ ํญ๋ชฉ ๋ฐ์ดํฐ๊ฐ ๋ง์ผ๋ฉด ๋ง์ ์๋ก ์ฑ๋ฅ ์ ํฐ ์ฐจ์ด๋ฅผ ๋ณด์ผ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ต๋๋ค.
์ด์ ๋ํด ํ
์คํธ๋ฅผ ์งํํด๋ณด์๊ณ , ์ค์ ๋ก ๋๋ฏธ ๋ฐ์ดํฐ๋ฅผ ๊ฐ ํ ๋ณ๋ก ํฌํ๋ฅผ 30 โ 60, ํฌํ ๋ณ๋ก ํฌํ ํญ๋ชฉ์ 3 โ 5๋ก ๋ณ๊ฒฝํ๊ณ ์ธก์ ํ์์ ๋ ์ฑ๋ฅ ์ธก์ ์ ์งํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์์ต๋๋ค.
// ๋ฐ์ ๊ทํ ์งํ ์
์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 2157.065458 ms, ์ฟผ๋ฆฌ ๊ฐ์: 10, ์ฟผ๋ฆฌ ์๊ฐ: 1168.891168 ms
// ๋ฐ์ ๊ทํ ์งํ ํ
์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 163.363125 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 24.577707 ms
YAML
๋ณต์ฌ
์ด์ ๋๋ถ์ด, ์กฐํ ๋น์ค์ด ํฌํ ๋น์ค๋ณด๋ค ๋ ๋๊ธฐ๋๋ฌธ์ update ์ถ๊ฐ ์ฟผ๋ฆฌ๊ฐ ๋๊ฐ๋ ๋จ์ ๋ณด๋ค๋ ์กฐํ ์ฑ๋ฅ์ ํจ์จ์ ์ฅ์ ์ด ๋ ํฌ๋ค๊ณ ํ๋จํ์์ต๋๋ค.
๋์์ฑ ๋ฌธ์
์ฒ์์๋ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒ์ ์ธ์งํ์ง ๋ชปํ์ต๋๋ค. ํ์ง๋ง MySQL ๊ณผ ๋ฉํฐ ์ฐ๋ ๋ ํ๊ฒฝ์ ๋ํด ์กฐ๊ธ ๋ ๊ณต๋ถํ๋ค ๋ณด๋ ๋์์ฑ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ ๊ฒ์ ์ธ์งํ๊ฒ ๋์์ต๋๋ค.
ํ์ฌ์ ๋ก์ง์ ์กฐํ์ ๋๋ถ์ด ์์ ํ๋ ๋ก์ง์ด ์ถ๊ฐ๋์ด ์ฌ๋ฌ ํธ๋์ญ์
์์ ๋์์ ์ ๊ทผํ ๊ฒฝ์ฐ ์ ํฉ์ฑ ๋ฌธ์ ๋ฟ๋ง ์๋๋ผ ์ฌํ๋ฉด ๋ฐ๋๋ฝ๊น์ง ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด์ ๋ฐ๋ผ ํด๋น API ๋ ๋์์ฑ ๋ฌธ์ ํด๊ฒฐ์ด ํ์์ ์ด์๊ณ ์ด๋ ๋์์ฑ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํด๋ณด์(๋น๊ด์ ๋ฝ, ๋๊ด์ ๋ฝ) ํฌ์คํ
์์ ํด๊ฒฐํ๋ ๊ณผ์ ์ ๋ด์์ต๋๋ค.
์ธ๋ฑ์ค ์ถ๊ฐ
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 279.455596 ms, ์ฟผ๋ฆฌ ๊ฐ์: 7, ์ฟผ๋ฆฌ ์๊ฐ: 238.463966 ms
YAML
๋ณต์ฌ
@Query("SELECT p FROM Poll p WHERE p.menu.code.code = :code")
Optional<Poll> findByCode(@Param("code") String code);
Java
๋ณต์ฌ
ํ์ฌ ์ ํฌ ๋ก์ง์์๋ ํฌํ ์กฐํ ์ code๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. code์ ๊ฒฝ์ฐ ๊ฐ ํฌํ์ ๊ณ ์ ํ ์๋ณ์์ด๊ธฐ ๋๋ฌธ์ ์นด๋๋๋ฆฌํฐ๊ฐ ๋งค์ฐ ๋์ต๋๋ค. ๊ทธ๋์ ์ ํฌ๋ ํฌํ์ ์๋ณ์์ธ code์๋ง ์ธ๋ฑ์ค๋ฅผ ์ถ๊ฐํ๊ธฐ๋ก ๊ฒฐ์ ํ์ต๋๋ค.
uri: '/api/groups/00000002/polls/qoZ9oDrz', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 52.782685 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 5.310012 ms
YAML
๋ณต์ฌ
๊ฐ์ ์ /ํ๋ฅผ ๋น๊ตํด๋ณด๋ ์ ์ฒด์ ์ผ๋ก ์ฒ๋ฆฌ ์๊ฐ์ด ํ์ฐํ ๊ฐ์ ๋ ๋ชจ์ต์ ๋ณด์์ต๋๋ค.
Unique ๋?
ํ, ํฌํ, ์ฝ์์ก๊ธฐ์ ๊ฐ์ ์ ํฌ ํ๋ก์ ํธ์ ๋๋ฉ์ธ๋ค์ ๋ชจ๋ ๋๋ค์ผ๋ก ์์ฑํ ์ฝ๋๋ฅผ ๊ฐ์ง๊ณ ์๊ณ , ์ด ์ฝ๋๋ฅผ ์๋ ์ฑ๋ฒ ๋ฐฉ์์ผ๋ก ์์ฑํ id ๋์ url ์๋ณ์๋ก ์ฌ์ฉํฉ๋๋ค. ํด๋น ์ฝ๋๋ 8์๋ฆฌ์ ์๋ฌธ์, ๋๋ฌธ์, ์ซ์ ์กฐํฉ์ผ๋ก ๊ตฌ์ฑ๋๊ณ ๋จ์ ๊ณ์ฐํ๋ฉด 62^8 ๊ฐ์ ๊ฐ์ง์๋ฅผ ๊ฐ์ง๊ธฐ๋๋ฌธ์, ์ค๋ณต๋ ๊ฐ๋ฅ์ฑ์ด ๊ฑฐ์ ์์ต๋๋ค. ์ด์ ๋ฐ๋ผ DB ์ ์ฝ ์กฐ๊ฑด์ผ๋ก unique ๋ฅผ ๋ฃ๋ ๋ฐฉ๋ฒ๋ ์๊ฐํด ๋ณด์์ต๋๋ค.
์ด์ ๋ฐ๋ผ ์ฑ๋ฅ ๊ฐ์ ์ด๊ธฐ์๋ unique ์ ์ฝ ์กฐ๊ฑด์ ์ถ๊ฐํ์ฌ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํ์์ต๋๋ค. ํ์ง๋ง Real MySQL 8.0 ์ ์ธ๋ฑ์ค ์ฑํฐ๋ฅผ ๊ณต๋ถํ๊ณ ๋๋ ์๊ฐํ๋ ๊ฒ๊ณผ ๋ฌ๋์ต๋๋ค.
๋จผ์ unique ์ ์ธ๋ฑ์ค์์ ์ฌ์ฉ๋๋ ์คํ ๊ณํ์ ๋ค๋ฅธ๋ฐ ์กฐํํ ๊ฐ์ด ํ๋๋ผ๋ฉด ํฌ๊ฒ ์ฐจ์ด๋ ์๋ค๊ณ ํฉ๋๋ค.
์์ ์ด๋ฏธ์ง๋ unique ์ ์ฝ์กฐ๊ฑด์ผ๋ก ์คํ ๊ณํ์ ํ์ธํ ์ด๋ฏธ์ง์ด๊ณ , ์์ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด ์คํ ๊ณํ์ ํ์ธํ ์ด๋ฏธ์ง์ ๋น๊ตํด ๋ณด๋ฉด type ์ปฌ๋ผ์ const ์ ref ์์ ์ฐจ์ด๊ฐ ์์ต๋๋ค. ์ด ๋์ PK, unique ์ ๊ฐ์ด ํ๋๊ฐ ํ์คํ ํค๋ก ์กฐํํ๋์ง, ์ด์ธ์ index ๋ก ์กฐํํ๋์ง์ ์ฐจ์ด์
๋๋ค. ๊ทธ๋์ ref๋ก ์กฐํํ ์ปฌ๋ผ์ ์นด๋๋๋ฆฌํฐ๊ฐ ๋์ ํ๋์ ๊ฐ๋ง ๊ฒ์ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด, ์ฑ๋ฅ์์๋ ๊ฑฐ์ ์ฐจ์ด๊ฐ ์๋ค๊ณ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ๋ํฌ ์ธ๋ฑ์ค๋ฅผ ์ฌ์ฉํ๋ฉด ์๋ก์ด ๋ ์ฝ๋๊ฐ insert ๋๊ฑฐ๋ ํด๋น ์ปฌ๋ผ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ ๊ฒฝ์ฐ, ์ค๋ณต๋ ๊ฐ์ด ์๋์ง ์๋์ง ์ฒดํฌํ๋ ๊ณผ์ ์ด ํ ๋จ๊ณ ๋ ํ์ํ์ฌ ๋๋ฆฝ๋๋ค. ์ ํฌ๊ฐ ์์ฑํ ์ฝ๋๋ 62^8 ์ ํ๋ฅ , ์ฝ 1/210์กฐ ์ด๊ธฐ๋๋ฌธ์ ๊ตณ์ด ์ค๋ณต๋ ๊ฐ์ ํ์ธํ ํ์๊ฐ ์๋ค๊ณ ํ๋จํ์์ต๋๋ค.
๋ํ ์ ๋ํฌ ์ธ๋ฑ์ค์์ ์ค๋ณต๋ ๊ฐ์ ์ฒดํฌํ ๋๋ ์ฝ๊ธฐ ์ ๊ธ, ์ฐ๊ธฐ ํ ๋๋ ์ฐ๊ธฐ ์ ๊ธ์ด ๊ฑธ๋ฆฌ๊ณ , ์ด ๊ณผ์ ์์ ์์์น ๋ชปํ ๋ฐ๋๋ฝ์ด ๋ฐ์ํ ์ ์์ต๋๋ค.
์ด๋ฌํ ์ด์ ๋ค๋๋ฌธ์ unique ์ ์ฝ ์กฐ๊ฑด์ ๋ผ๊ณ ๋ค์ ์ธ๋ฑ์ค๋ฅผ ๋ง๋ค์ด ์ฌ์ฉํ์์ต๋๋ค.
๊ฒฐ๊ณผ
์์ ๋ด์ฉ์ผ๋ก ๊ฐ์ ํ ๋ค ๋ค์ ํ
์คํธ๋ฅผ ๋๋ ค ๋ณธ ๊ฒฐ๊ณผ์
๋๋ค.
[ํฌํ ์ฑ๋ฅ ํ
์คํธ]
// before
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 4148.619320 ms, ์ฟผ๋ฆฌ ๊ฐ์: 124, ์ฟผ๋ฆฌ ์๊ฐ: 2123.705562 ms
uri: '/api/groups/00000002/polls', method: 'POST', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 476.378221 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 14.347752 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 279.455596 ms, ์ฟผ๋ฆฌ ๊ฐ์: 7, ์ฟผ๋ฆฌ ์๊ฐ: 238.463966 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/items', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 1295.610065 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 1235.628151 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 153.095624 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 4.681824 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 28.595276 ms, ์ฟผ๋ฆฌ ๊ฐ์: 8, ์ฟผ๋ฆฌ ์๊ฐ: 4.014231 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 92.646055 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 6.505827 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/result', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 68.598734 ms, ์ฟผ๋ฆฌ ๊ฐ์: 8, ์ฟผ๋ฆฌ ์๊ฐ: 2.851347 ms
uri: '/api/groups/00000002/polls/ZEdlKskY/close', method: 'PATCH', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 39.222127 ms, ์ฟผ๋ฆฌ ๊ฐ์: 5, ์ฟผ๋ฆฌ ์๊ฐ: 1.428766 ms
uri: '/api/groups/00000002/polls/ZEdlKskY', method: 'DELETE', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 173.856499 ms, ์ฟผ๋ฆฌ ๊ฐ์: 10, ์ฟผ๋ฆฌ ์๊ฐ: 136.763482 ms
// after
uri: '/api/groups/00000002/polls', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 130.732916 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 15.434725 ms
uri: '/api/groups/00000002/polls', method: 'POST', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 92.129583 ms, ์ฟผ๋ฆฌ ๊ฐ์: 7, ์ฟผ๋ฆฌ ์๊ฐ: 6.798292 ms
uri: '/api/groups/00000002/polls/rFdex7qg', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 52.782685 ms, ์ฟผ๋ฆฌ ๊ฐ์: 4, ์ฟผ๋ฆฌ ์๊ฐ: 5.310012 ms
uri: '/api/groups/00000002/polls/rFdex7qg/items', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 23.762750 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 1.143833 ms
uri: '/api/groups/00000002/polls/rFdex7qg', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 87.143708 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 7.733458 ms
uri: '/api/groups/00000002/polls/rFdex7qg', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 12.067208 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 0.728125 ms
uri: '/api/groups/00000002/polls/rFdex7qg', method: 'PUT', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 16.042375 ms, ์ฟผ๋ฆฌ ๊ฐ์: 9, ์ฟผ๋ฆฌ ์๊ฐ: 1.707665 ms
uri: '/api/groups/00000002/polls/rFdex7qg/result', method: 'GET', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 21.225875 ms, ์ฟผ๋ฆฌ ๊ฐ์: 7, ์ฟผ๋ฆฌ ์๊ฐ: 0.516291 ms
uri: '/api/groups/00000002/polls/rFdex7qg/close', method: 'PATCH', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 17.626834 ms, ์ฟผ๋ฆฌ ๊ฐ์: 6, ์ฟผ๋ฆฌ ์๊ฐ: 1.552708 ms
uri: '/api/groups/00000002/polls/rFdex7qg', method: 'DELETE', ์์ฒญ ์ฒ๋ฆฌ ์๊ฐ: 18.157208 ms, ์ฟผ๋ฆฌ ๊ฐ์: 10, ์ฟผ๋ฆฌ ์๊ฐ: 1.686958 ms
Java
๋ณต์ฌ
๊ฐ๊ฐ์ ํ๊ท ์ ํ๋ก ์ ๋ฆฌํด ๋ณด์์ต๋๋ค.
์ฟผ๋ฆฌ ๊ฐ์ | ์ฟผ๋ฆฌ ์๊ฐ | |
before | 19.2 | 376.3 |
after | 6.8 | 40.5 |
๊ฐ์ ์ ๊ณผ ๋น๊ตํ์ฌ ์ฟผ๋ฆฌ ๊ฐ์๋ ์ฝ 3๋ฐฐ, ์ฟผ๋ฆฌ ์๊ฐ์ ์ฝ 10๋ฐฐ ์ ๋ ๊ฐ์ ๋ ๊ฒ์ ํ์ธํ ์ ์์ต๋๋ค.