Backend with Golang

[MySQL] Update Data in Batches

아직개구리 2023. 9. 19. 13:04

How to update data in batches 

  1. IN : 특정 값 여러개를 선택하기 위해서 사용되는 연산자이기 때문에, updated result가 하나로밖에 안되는 한계점이 있다.  
    • Update users Set status=1 Where account IN ('xx1', 'xx2') : 만약 여기서 1이 아니고 몇개는 1, 다른 몇개는 2 로 바꾸고 싶을 때 IN을 사용해서 하나의 statement 로는 불가능하고, 여러개의 SQL statement로만 가능하다. 
  2.  For + UPDATE : for loop + update statement 
    • intuitive, 거의 대부분의 상황에 적용 가능하며, 실수가 잘 일어나지 않는다. 하지만 단점으로는 performance가 별로다.  
  3. INSERT INTO ... ON DUPLICATE KEY
    • primary key의 uniqueness를 사용해서 batch updates를 지원한다. 이때 update results는 consistent할 필요가 없다. 
    • 단점으로는 모든 field가 default value (including NULL)이 있어야 한다. 이렇지 않으면 insert자체가 안되기 때문에 update문이 실행되지 않는다. 

Values 와 Select 

Select 문을 통해서 다른 테이블의 있는 정보를 Values 안에 넣고 싶을 때, Values 안에 select를 넣을 수 있나 해서 찾아봤는데 아래의 글을 발견했다. 내가 원했던 동작은 다른 테이블의 있는 id를 사용해서 중복 체크를 해서 update를 하는 것이었는데, 아래의 경우 1번을 사용했다.

 

1. Approach for With SELECT subquery returning results with one row.

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
VALUES ('DUMMY1', (SELECT <field> FROM <table_name> ),'DUMMY2');

이 경우, select sub-query가 하나의 row만 리턴하는 경우이다. 예를 들어 where condition을 사용하던, SQL의 aggregation function (ex: SUM, MAX, AVG)같은 걸 사용하는 경우가 있다. 여러개의 row를 return하면 에러가 난다. 

 

2. Approach for With SELECT subquery returning results with multiple rows.

INSERT INTO <table_name> (<field1>, <field2>, <field3>) 
SELECT 'DUMMY1', <field>, 'DUMMY2' FROM <table_name>;

이 경우는 여러개의 row를 return하는 select문일때 사용할 수 있다. 

Reference 

  1. https://medium.com/javarevisited/6-ways-to-update-data-in-batches-in-mysql-b6facc0a6c22
  2. https://stackoverflow.com/questions/25969/insert-into-values-select-from  

'Backend with Golang' 카테고리의 다른 글

[Go] 재선언과 재할당  (0) 2023.11.11
[Concurrency in Go] 비정상 고루틴의 치료 (steward & ward)  (0) 2023.11.10
[Concurrency-6] Or-done channel  (0) 2023.09.14
[Concurrency-5] Fan-Out, Fan-In  (0) 2023.09.12
Rate Limiting  (1) 2023.09.06