Search
Duplicate
๐ŸŽจ

๋‹ค์‚ฌ๋‹ค๋‚œ ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„ - ์‹ฌํ™”ํŽธ

์ƒ์„ฑ์ผ
2022/12/20
ํƒœ๊ทธ
Spring
MySQL
Refactoring
์ด ํฌ์ŠคํŒ…์€ ์•ž์˜ ๋„๋ฉ”์ธ ๊ตฌ์กฐ ์šฐ์•„ํ•˜๊ฒŒ ์„ค๊ณ„ํ•˜๊ธฐ ๋‚ด์šฉ์— ์ด์–ด์„œ ์ž‘์„ฑ๋ฉ๋‹ˆ๋‹ค.
๋ชฉ์ฐจ

๋ฐฐ๊ฒฝ

์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ƒํ˜ธ ๊ฐ์ฒด๊ฐ„ ์˜์กด๋„๋ฅผ ๋‚ฎ์ถ”๊ณ , ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ๋„๋ฉ”์ธ ๊ฐ์ฒด๋กœ ๋„ฃ์–ด ์‘์ง‘๋„๋ฅผ ๋†’์ด๋Š” ๋„๋ฉ”์ธ ์žฌ์„ค๊ณ„๋ฅผ ์ง„ํ–‰ํ•˜๊ณ  ์ ์šฉํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์—์„œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์ด ์„œ๋น„์Šค ๊ณ„์ธต์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ๋ฉ”์„œ๋“œ์—์„œ ๋„๋ฉ”์ธ ๊ฐ์ฒด ๋‚ด๋ถ€๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜์—ˆ๊ณ , ๋Œ€๋ถ€๋ถ„์˜ ์ฟผ๋ฆฌ๋ฅผ 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+1)+1=Nโˆ—M+N+1N(M + 1) + 1 = N * M + 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๋ฐฐ ์ •๋„ ๊ฐœ์„ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.