본문 바로가기
  • 소소한 개발자 이야기
Software/알고보면 쓸모있는 코딩스킬

실무에서 UPDATE 쿼리를 사용할 때 주의할 점

by Siwan_Min 2023. 5. 7.
728x90

안녕하세요. 

오늘은 우리 회사에서 겪었던 이슈? 에 대하여 포스팅을 할까 합니다. 

 

우리 회사에서는 mariaDB를 사용하고 있고 특정 시간대에  Write DB의 성능 지연으로 인해 RestAPI에서 INSERT를 수행할 시에 20초 이상 지연되는 것을 스카우터를 통해 확인 했습니다. 매일 똑같은 시간대에 현상이 발생하는 걸 토대로 그 시간에 수행되는 배치 의심하기 시작했습니다. 조사 후 우리는 일괄 UPDATE 가 범인임을 알아냈습니다. 그렇다면 왜 일괄 UPDATE가 문제가 된다는 걸까요?

 

사실 일괄 업데이트라는 용어가 정확히 있는지도 잘 모르겠습니다. 여기서 말하는 일괄 업데이트는 하나의 업데이트 쿼리로 많은 양의 레코드를 UPDATE(수정) 할 수 있는 것을 말합니다. 당연히 단일 쿼리로 여러 레코드를 일괄적으로 업데이트 할 수 있다고 하니 유용하다고 생각 할 수 있습니다. 하지만 이것은 잘못 사용할 경우 큰 성능저하를 일으킬 수 있습니다. 

 

예를 들어 보겠습니다. 

 

String query = "UPDATE homework_table
SET status = 'completed'
WHERE submit_date IS NOT NULL";

try {
	dao.update(query);
} catch (Exception e) {
	log.Error("batch 수행 에러 {}", e);
}

 

이 쿼리를 매일 00시 10분에 수행하는 배치 클래스가 있다고 가정해 봅시다. 

00시 10 분을 기준으로 제출날짜(submit_date) 가 있는 학생의 상태 컬럼은 completed 로 update 할 것입니다. 이렇게 보면 문제가 없어 보이지만 조금 깊게 들어가 보면 문제가 발생할 여지를 캐치할 수 있습니다. 만약 homework_table의 레코드가 무수히 많다면 어떻게 될까요??  데이터베이스의 작업이 트랜잭션 시작 - 쿼리 - 커밋 순으로 일어나는 것을 우리가 알고 있을때, 위 쿼리를 수행한다면 쿼리가 수행되고 커밋이 완료되는 동안 write DB는 일관성과 무결성을 보장하기 위해 테이블은 commit이 완료되기까지 lock이 걸린 상태가 될 것이고, 그 사이에 해당 테이블(homework_table)로 들어온 다른 INSERT, UPDATE, DELETE 쿼리 또한 대기 상태가 될 것이며 그로인해 성능저하가 발생하게 된다는 것을 알 수 있습니다.

 

그렇다면 어떻게 해결할 수 있을까요?? 그것은 바로 select를 통해 수정해야 할 모수를 뽑아 단일로 update를 수행하는 것 입니다. 

 

예시

public void excuteBatch() {

    String query = "Select id, name, age, gender 
    				from homework_table 
                    where submit_date is not null"
                    
	ResultSet resultSet = dao.select(query);
    
    while(resultSet.next()) {
    	
        Student student = new Student();
        student.setId(resultSet.getId());
        student.setName(resultSet.getName());
        .... 
        
        dao.update("update homework_table
        			set status = 'completed'
                    where id = ?,
                    	name = ?
                        ...
					", student);            	
    }
}

 

어떤 느낌인지 이해하셨나요?? 이렇게 하면 update 를 일괄로 진행하지 않고 단건으로 처리하기 때문에 중간에 들어오는 다른 쿼리문을 수행할 수 있습니다. 이것은 예시일 뿐 각자 프레임워크에 맞게 구현하면 됩니다 

 

지금까지 실무에서 겪은 일괄 업데이트 쿼리 문의 문제점과 그를 해결하는 방안에 대해 작성해 보았습니다. 

 

이상입니다. 

 

감사합니다. 

 

 

 

728x90

댓글