[OneTime] ๐Ÿš€ ์„ฑ๋Šฅ ๊ฐœ์„ ์ผ์ง€ 2 (feat. Bulk Insert)

Sangho Hanยท2025๋…„ 5์›” 25์ผ
5

โฐ OneTime

๋ชฉ๋ก ๋ณด๊ธฐ
6/7
post-thumbnail

โฐ OneTime?

์›ํƒ€์ž„์— ๋Œ€ํ•ด์„œ ๊ถ๊ธˆํ•˜๋‹ค๋ฉด ์•„๋ž˜๋ฅผ ์ฐธ๊ณ ํ•ด์ฃผ์„ธ์š”!

โฐ OneTime ์„œ๋น„์Šค ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“ OneTime ์†Œ๊ฐœ๊ธ€
๐Ÿง‘๐Ÿปโ€๐Ÿ’ป GitHub
๐Ÿ“ธ Instagram


๐ŸŽฌ ์„œ๋ก 

์ง€๋‚œ ์„ฑ๋Šฅ ๊ฐœ์„ ๊ธฐ1์—์„œ๋Š” ์กฐํšŒ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ, N+1 ๋ฌธ์ œ ํ•ด๊ฒฐ๊ณผ ์ธ๋ฑ์Šค๋ฅผ ์ ์šฉํ•ด ๋ณด์•˜๋‹ค.

์ด๋ฒˆ์—๋Š” ์ด๋ฒคํŠธ ์ƒ์„ฑ API์— ๋Œ€ํ•œ ๊ฐœ์„ ์„ ์—ฌ๋Ÿฌ ๋ฐฉ๋ฉด์œผ๋กœ ๋„์ „ํ•ด ๋ณผ ๊ณ„ํš์ด๋‹ค. ํ•ด๋‹น ๊ธ€์€ ์ด์— ๋Œ€ํ•œ ๋‚ด์šฉ์œผ๋กœ ์ด์–ด์ง„๋‹ค.


์ด๋ฒคํŠธ ์ƒ์„ฑ API

๋ณดํ†ต์˜ ๊ฒฝ์šฐ์—๋Š” ํฌ๊ฒŒ ๋ณ‘๋ชฉ์ด ์ƒ๊ธฐ๋Š” ์ผ์€ ์—†์œผ๋‚˜, ์œ„์™€ ๊ฐ™์ด ํ•œ ๋‹ฌ์„ ํ†ต์งธ๋กœ ๋ฒ”์œ„๋กœ ์ง€์ •ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ƒ์„ฑํ•˜๋Š” ๋ฐ ๊ฝค ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ์‹œ๊ฐ„๋„ 00:00 ~ 24:00์œผ๋กœ ํ•œ๋‹ค๋ฉด ๋”์šฑ ๊ทธ๋ ‡๋‹ค.

์‹ค์ œ๋กœ ์œ„์™€ ๊ฐ™์ด ์ด๋ฒคํŠธ๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•˜์‹œ๋Š” ์œ ์ €๋ถ„๋“ค๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฒคํŠธ ์ƒ์„ฑ ์ฒ˜๋ฆฌ ์†๋„ ๊ฐœ์„ ์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ํŒ๋‹จ๋˜์—ˆ๋‹ค.

์ดˆ๊ธฐ ์„ฑ๋Šฅ ์ธก์ •

์„ฑ๋Šฅ ์ธก์ • ํˆด์€ Grafana K6๋ฅผ ์‚ฌ์šฉํ•˜์˜€๋‹ค.

๋˜ํ•œ ์•„๋ž˜์˜ ์กฐ๊ฑด์„ ๊ณ ์ •์œผ๋กœ ๋‘์–ด ์ธก์ •ํ•˜์˜€๋‹ค.

1) 5๋ช…์˜ ๋™์‹œ ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ธ์ถœ : vus: 5
2) 20๋ฒˆ ํ˜ธ์ถœ ์‹œ ์ข…๋ฃŒ : iterations: 20
3) 6์›” 1์ผ ~ 6์›” 30์ผ / 00:00 ~ 24:00 ๋กœ ๋ฒ”์œ„ ์ง€์ •

์กฐํšŒ์— ๋น„ํ•ด์„œ ๋นˆ๋ฒˆํ•˜๊ฒŒ ์ด๋ฃจ์–ด์ง€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๊ธฐ๋„ ํ•˜๊ณ , ํ˜ธ์ถœ์„ ๋„ˆ๋ฌด ๋งŽ์ด ์žก์œผ๋ฉด ํ…Œ์ŠคํŠธ ์‹œ๊ฐ„์ด ๊ณผ๋„ํ•˜๊ฒŒ ์†Œ์š”๋˜์–ด์„œ ์œ„์™€ ๊ฐ™์ด ์ง€์ •ํ•˜์˜€๋‹ค.

์ดˆ๊ธฐ์—๋Š” ์œ„์™€ ๊ฐ™์ด ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„์ด 16.56s๋กœ ์ธก์ •๋˜์—ˆ๋‹ค.

๋ณ‘๋ชฉ ์ง€์  ์ฐพ๊ธฐ : StopWatch

Spring์˜ StopWatch๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…์˜ ์‹คํ–‰ ์‹œ๊ฐ„์„ ์ธก์ •ํ•˜์—ฌ, ์–ด๋–ค ์ž‘์—…์ด ์„ฑ๋Šฅ ๋ณ‘๋ชฉ์„ ์œ ๋ฐœํ•˜๋Š”์ง€ ๋ถ„์„ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•œ ๋„๊ตฌ์ด๋‹ค.

ํ˜„์žฌ ์ธ์ฆ ์‚ฌ์šฉ์ž์˜ ์ด๋ฒคํŠธ๋ฅผ ์ƒ์„ฑํ•ด ์ฃผ๋Š” createEventForAuthenticatedUser ๋ฉ”์„œ๋“œ๋Š” ์—ฌ๋Ÿฌ ์ž‘์—…(save, QR ์ƒ์„ฑ, ์Šค์ผ€์ค„ ์ €์žฅ)์„ ํฌํ•จํ•˜๊ณ  ์žˆ๋‹ค.

์ด๋ฅผ ์ •๋ฐ€ํ•˜๊ฒŒ ๋ถ„์„ํ•˜๊ธฐ ์œ„ํ•ด, StopWatch๋กœ ๊ฐ ๋‹จ๊ณ„์˜ ์†Œ์š” ์‹œ๊ฐ„์„ ์ธก์ •ํ•ด ๋ณด์•˜๋‹ค.

    @Transactional
    public CreateEventResponse createEventForAuthenticatedUser(CreateEventRequest createEventRequest, String authorizationHeader) {
        StopWatch stopWatch = new StopWatch("CreateEvent");

        stopWatch.start("saveEvent");
        Event savedEvent = eventRepository.save(createEventRequest.toEntity());
        stopWatch.stop();

        stopWatch.start("createQrCode");
        createAndAddQrCode(savedEvent);
        stopWatch.stop();

        stopWatch.start("saveParticipation");
        User user = jwtUtil.getUserFromHeader(authorizationHeader);
        EventParticipation eventParticipation = EventParticipation.builder()
                .user(user)
                .event(savedEvent)
                .eventStatus(EventStatus.CREATOR)
                .build();
        eventParticipationRepository.save(eventParticipation);
        stopWatch.stop();

        stopWatch.start("saveSchedules");
        validateAndSaveSchedules(savedEvent, createEventRequest);
        stopWatch.stop();

        log.info("\nโœ… [CreateEvent ํ”„๋กœํŒŒ์ผ๋ง ๊ฒฐ๊ณผ]\n{}", stopWatch.prettyPrint());

        return CreateEventResponse.of(savedEvent);
    }
โœ… [CreateEvent ํ”„๋กœํŒŒ์ผ๋ง ๊ฒฐ๊ณผ]
StopWatch 'CreateEvent': 17.522903625 seconds
---------------------------------------------
Seconds       %       Task name
---------------------------------------------
00.01018171   00%     saveEvent
00.13092308   01%     createQrCode
00.03012458   00%     saveParticipation
17.35167425   99%     saveSchedules

๋ถ„์„ ๊ฒฐ๊ณผ, ์ด ์†Œ์š” ์‹œ๊ฐ„์€ ์•ฝ 17.5์ดˆ์˜€์œผ๋ฉฐ, ์ด ์ค‘ 99% ์ด์ƒ์ด saveSchedules ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

์ด๋Š” ์ด๋ฒคํŠธ ์ƒ์„ฑ ์‹œ, 30๋ถ„ ๋‹จ์œ„ ์Šค์ผ€์ค„์„ ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ๊ณผ์ •์—์„œ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ์ด ๋ฐœ์ƒํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๊ธฐ์—, ์ด๋ฅผ ์šฐ์„ ์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๊ณ ์ž ํ•˜์˜€๋‹ค.


๐Ÿšจ ๋ฌธ์ œ 1 : ์•ฝ 3๋งŒ ๊ฐœ์˜ INSERT

48 (30๋ถ„ ๋‹จ์œ„ ์Šค์ผ€์ค„) ร— 30 (์ผ) ร— 20 (์š”์ฒญ ์ˆ˜)  
= 28,800๊ฐœ์˜ Schedule insert

์œ„์—์„œ ๊ฐ€์ •ํ•œ ๋Œ€๋กœ๋ผ๋ฉด, 20๋ฒˆ ํ˜ธ์ถœ์„ ํ–ˆ์„ ๋•Œ ๋ฐœ์ƒํ•˜๋Š” INSERT ์—ฐ์‚ฐ์€ ์ด 28,800๋ฒˆ์ด ๋œ๋‹ค.
saveAll์ด save ์— ๋น„ํ•ด ์„ฑ๋Šฅ์ด ์ข‹์ง€๋งŒ, ์ด ๋˜ํ•œ ๊ฒฐ๊ตญ์—๋Š” save ๋ฌธ์„ ํ•œ ๋ฒˆ์”ฉ ํ˜ธ์ถœํ•˜๋Š” ๊ตฌ์กฐ๊ฐ€ ๋œ๋‹ค.

์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ, Bulk Insert ๋ฐฉ์‹์„ ํ™œ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

โœ… ํ•ด๊ฒฐ ๋ฐฉ์•ˆ : Bulk Insert

Bulk Insert๋ž€?

Bulk Insert๋Š” ๋‹ค์ˆ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์˜ ์ฟผ๋ฆฌ๋กœ ๋ฌถ์–ด ๋Œ€๋Ÿ‰์œผ๋กœ ์‚ฝ์ž…ํ•˜๋Š” ๋ฐฉ์‹์„ ์˜๋ฏธํ•œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ์ผ๋ฐ˜์ ์ธ insert๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•˜๋‚˜์˜ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•œ๋‹ค:

insert into schedules (date, time) values ('2025.06.01', '09:00');
insert into schedules (date, time) values ('2025.06.01', '09:30');
insert into schedules (date, time) values ('2025.06.01', '10:00');
...

ํ•˜์ง€๋งŒ Bulk Insert๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹ค์ˆ˜์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ์ฟผ๋ฆฌ๋กœ ๋ฌถ์–ด ์ „์†กํ•จ์œผ๋กœ์จ, DB์™€์˜ ํ†ต์‹  ํšŸ์ˆ˜๋ฅผ ์ค„์ด๊ณ  ์„ฑ๋Šฅ์„ ํฌ๊ฒŒ ํ–ฅ์ƒ์‹œํ‚จ๋‹ค:

insert into schedules (date, time) values 
('2025.06.01', '09:00'), 
('2025.06.01', '09:30'), 
('2025.06.01', '10:00');

์ด ๋ฐฉ์‹์€ ํŠนํžˆ ์ˆ˜์ฒœ, ์ˆ˜๋งŒ ๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์—์„œ ํšจ๊ณผ๊ฐ€ ํฌ๋ฉฐ, ๋Œ€๋Ÿ‰ ์ €์žฅ ์ž‘์—…์˜ ์„ฑ๋Šฅ ๋ณ‘๋ชฉ์„ ํ•ด๊ฒฐํ•˜๋Š” ์ฃผ์š” ์ „๋žต ์ค‘ ํ•˜๋‚˜๋กœ ํ™œ์šฉ๋˜๊ณค ํ•œ๋‹ค.

IDENTITY ์ „๋žต์€ Bulk Insert ์‚ฌ์šฉ์ด ๋ถˆ๊ฐ€?

์—ฌ๊ธฐ์„œ ํ•œ ๊ฐ€์ง€ ์ œ์•ฝ์ด ์กด์žฌํ–ˆ๋‹ค.
๋‚˜๋Š” ๋ณดํ†ต id์— ๋Œ€ํ•ด์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด IDENTITY ์ „๋žต์„ ํ™œ์šฉํ•ด ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

ํ•˜์ง€๋งŒ ํ•ด๋‹น ์ „๋žต์„ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” Hibernate batch insert ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋ฐ ๊ทธ ์ด์œ ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  1. IDENTITY๋Š” DB์—์„œ insert ์‹œ์ ์— ID๋ฅผ ์ƒ์„ฑํ•จ
  2. ์ฆ‰, ๊ฐ row๋งˆ๋‹ค insert ํ›„์— DB์—์„œ auto_increment๋œ PK๋ฅผ ๋ฐ›์•„์™€์•ผ ํ•จ
  3. Hibernate batch insert๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ชจ๋“  ID๋ฅผ ๋ฏธ๋ฆฌ ์•Œ์•„์•ผ ํ•˜๋‚˜๋กœ ๋ฌถ์„ ์ˆ˜ ์žˆ์Œ
  4. ํ•˜์ง€๋งŒ IDENTITY๋Š” insert ํ›„์—์•ผ ID๋ฅผ ์•Œ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ•˜๋‚˜์”ฉ insertํ•  ์ˆ˜๋ฐ–์— ์—†์Œ

๋Œ€์•ˆ : JdbcTemplate์„ ํ™œ์šฉํ•œ ์ง์ ‘ Bulk Insert

Hibernate์˜ ์ œ์•ฝ ์‚ฌํ•ญ์„ ์šฐํšŒํ•˜๊ธฐ ์œ„ํ•ด, Spring์˜ JdbcTemplate์„ ํ™œ์šฉํ•œ ์ง์ ‘ Bulk Insert ๋ฐฉ์‹์„ ํ™œ์šฉํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์ด๋ฅผ ํ†ตํ•ด @GeneratedValue(strategy = IDENTITY) ์ „๋žต์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ๋„, insert ์ฟผ๋ฆฌ๋ฅผ ํ•˜๋‚˜๋กœ ๋ฌถ์–ด ๋Œ€๋Ÿ‰ ์‚ฝ์ž…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

ScheduleBatchRepository

@Repository
@RequiredArgsConstructor
public class ScheduleBatchRepository {

    private final JdbcTemplate jdbcTemplate;

    public void insertAll(List<Schedule> schedules) {
        String sql = "INSERT INTO schedules (events_id, date, day, time, created_date, updated_date) VALUES (?, ?, ?, ?, ?, ?)";
        Timestamp now = Timestamp.valueOf(LocalDateTime.now());

        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                Schedule schedule = schedules.get(i);
                ps.setLong(1, schedule.getEvent().getId());
                ps.setString(2, schedule.getDate());
                ps.setString(3, schedule.getDay());
                ps.setString(4, schedule.getTime());
                ps.setTimestamp(5, now);
                ps.setTimestamp(6, now);
            }

            @Override
            public int getBatchSize() {
                return schedules.size();
            }
        });
    }
}

JDBC ํ…œํ”Œ๋ฆฟ์„ ํ™œ์šฉํ•˜๋Š” ScheduleBatchRepository๋ฅผ ๋งŒ๋“ค์–ด ์ค€ ํ›„์—, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์„œ๋น„์Šค ๋‹จ์—์„œ saveAll() ๋Œ€์‹  ํ˜ธ์ถœํ•˜๋„๋ก ํ•˜์˜€๋‹ค.

scheduleRepository.saveAll(schedules); // ๊ธฐ์กด

scheduleBatchRepository.insertAll(schedules); // ๋ณ€๊ฒฝ ํ›„

rewriteBatchedStatements=true

Bulk Insert๋ฅผ ์ ์šฉํ–ˆ์Œ์—๋„ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๊ฐ€ ๋‚˜ํƒ€๋‚˜์ง€ ์•Š์•˜๊ณ , SQL ๋กœ๊ทธ๋„ ์ถœ๋ ฅ๋˜์ง€ ์•Š์•„ ๋ฌธ์ œ์˜ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์› ๋‹ค.

์„œ์นญ์„ ํ•ด ๋ณธ ๊ฒฐ๊ณผ, MySQL์˜ ๊ฒฝ์šฐ rewriteBatchedStatements=true ์˜ต์…˜์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด JDBC ๋“œ๋ผ์ด๋ฒ„๊ฐ€ ์‹ค์ œ๋กœ ๋ฐฐ์น˜ ์ฟผ๋ฆฌ๋ฅผ ํ•˜๋‚˜์˜ ์ฟผ๋ฆฌ๋กœ ํ•ฉ์น˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค.

๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด DB URL์„ ์ˆ˜์ •ํ•˜์—ฌ ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•ด์ฃผ์—ˆ๋‹ค.

jdbc:mysql:// ... &rewriteBatchedStatements=true

๐Ÿ“Š ๊ฒฐ๊ณผ

Bulk Insert๋ฅผ ์ œ๋Œ€๋กœ ์ ์šฉํ•œ ๊ฒฐ๊ณผ, ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ 16.56s -> 0.41s๋กœ ํฌ๊ฒŒ ๊ฐœ์„ ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค!

โœ… [CreateEvent ํ”„๋กœํŒŒ์ผ๋ง ๊ฒฐ๊ณผ]
StopWatch 'CreateEvent': 0.215752875 seconds
--------------------------------------------
Seconds       %       Task name
--------------------------------------------
0.034693542   16%     saveEvent
0.0626085     29%     createQrCode
0.027162833   13%     saveParticipation
0.091288      42%     saveSchedules

๋ถ„์„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์•„๋„, saveSchedules๊ฐ€ ์ฐจ์ง€ํ•˜๋Š” ๋น„์œจ์ด ๋งŽ์ด ๋‚ฎ์•„์ง„ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

๐Ÿง‘๐Ÿปโ€๐Ÿ’ป ๋‹ค์Œ์œผ๋กœ ๋†’์€ createQrCode ๋‹จ๊ณ„์— ๋Œ€ํ•œ ๊ฐœ์„ ์„ ์ง„ํ–‰ํ•ด๋ณผ๊นŒ ํ•˜์˜€์ง€๋งŒ, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌ ํ•œ ํ›„ ์ธก์ •ํ•˜์˜€์„ ๋•Œ์—๋„ ์ฒ˜๋ฆฌ ์†๋„์˜ ์ฐจ์ด๊ฐ€ ๋ฏธ๋ฏธํ•˜์˜€๋‹ค.
๋•Œ๋ฌธ์— ๊ฐ€์žฅ ํฐ ๋ณ‘๋ชฉ ์ง€์ ์ด์—ˆ๋˜ saveSchedules ๋‹จ๊ณ„๋ฅผ ๊ฐœ์„ ํ•œ ๊ฒƒ์— ๋งŒ์กฑํ•˜๋ฉฐ ์—ฌ๊ธฐ์„œ ๋งˆ๋ฌด๋ฆฌ ํ•˜๊ณ ์ž ํ•œ๋‹ค.


๐Ÿ ๋งˆ๋ฌด๋ฆฌ

๐Ÿ’ก ๋А๋‚€ ์  ๋ฐ ๋ฐฐ์šด ์ 

  1. ํ…Œ์ŠคํŠธ ์ƒ์œผ๋กœ ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ 16.56s -> 0.41s (97.5%) ๊ฐœ์„ ๋˜์—ˆ๋‹ค.
  2. ๋‹ค๋Ÿ‰์˜ INSERT ๋ฌธ์ด ๋ฐœ์ƒํ•  ๋•Œ์—๋Š”, ์•ž์œผ๋กœ๋„ Bulk Insert๋ฅผ ๊ณ ๋ คํ•ด ๋ณด์•„์•ผ๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.
  3. Bulk Insert๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š”, rewriteBatchedStatements=true ์˜ต์…˜์„ ๊ผญ ์ง€์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.
  4. StopWatch ๋ผ๋Š” ์„ฑ๋Šฅ ์ธก์ • ํˆด์„ ์•Œ๊ฒŒ ๋˜์—ˆ๋‹ค. ์•ž์œผ๋กœ๋„ ์„ธ์„ธํ•˜๊ฒŒ ๋ณ‘๋ชฉ ์ง€์ ์„ ์ฐพ์•„๋‚ผ ๋•Œ ํ™œ์šฉํ•ด๋ณด์•„์•ผ๊ฒ ๋‹ค.
profile
์•ˆ๋…•ํ•˜์„ธ์š”. ๋น„์ฆˆ๋‹ˆ์Šค๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž, ํ•œ์ƒํ˜ธ์ž…๋‹ˆ๋‹ค.

0๊ฐœ์˜ ๋Œ“๊ธ€