1. 쿼리에서 select 한 값을 List(5만건)로 받아와서 foreach로 update 하기


foreach 방식일경우


1. 같은 행사번호에 10만원~20만원 사이 구매한 고객이 5만명이고 이 5만명이 각각 다른 응모자참여번호가 들어갈때

2. 응모자 5만명을 모두 당첨처리를 하기 위해선

3. 응모자참여번호 5만명을 SELECT 하여 Java에 List로 받아오고

4. List에 저장된 5만개의 응모자참여번호를 foreach를 통해 update를 5만번 실시함.

5. 같은 쿼리를 5만번이나 실행하니 비효율적이고 실행시간이 매우 오래걸리는 단점



1
2
3
4
5
//  1. 응모자참여번호 5만명을 SELECT 하여 Java에 List로 받아온다.
 
List<PrEvntTkpt> prEvntTkptList = commonEventsReadOnlyDAO.selectWinnerEvntTkptList( param);
 
//  prEvntTkptList에는 5만건의 데이터 가지고 있음.
cs


1
2
3
4
5
6
7
8
9
10
-- 2. 응모자 5만명을 모두 당첨처리를 하기 위해선
-- 5만명에 대한 각각의 응모자참여번호를 쿼리로 구해오고
-- <id= selectWinnerEvntTkptList>
 SELECT a.EVNT_PTCP_NO -- 이벤트 참여 번호
   FROM pr_evnt_ptcp_ord a -- 응모참여 주문테이블
  WHERE a.CMPN_NO = '1'
  GROUP BY a.EVNT_PTCP_NO, a.CMPN_NO
 HAVING SUM(a.PUR_RCGN_AMT) >= 100000
    AND SUM(a.PUR_RCGN_AMT) < 200000 
-- result return rows  50000
cs


1
2
3
4
5
6
7
8
9
10
11
// 3. foreach를 통해 List길이만큼 update를 5만번 실시함.
for( PrEvntTkpt prEvntTkpt : prEvntTkptList) { 
 
    data = new PrEvntTkpt();
    data.setEvntPtcpNo(prEvntTkpt.getEvntPtcpNo()); // 1 ~ 50000
    data.setModrId(param.getModrId()); // shlee0882
    data.setEvntTkptStatCd("10");    //당첨확정
 
    // 5만건 반복하며 update 실시
    result += commonEventsReadWriteDAO.updateEventWin( data );
}    
cs


1
2
3
4
5
6
7
-- 4. 아래의 같은 update 쿼리를 5만번이나 실행하니 비효율적이고 실행시간이 매우 오래걸리는 단점이 생김.
-- <id= updateEventWin>
    UPDATE pr_evnt_tkpt a
       SET EVNT_TKPT_STAT_CD = #{evntTkptStatCd} -- 10
         , MODR_ID = 'shlee0882'
     WHERE a.CMPN_NO = '2'
       and evnt_ptcp_no = #{evntPtcpNo} -- 1~50000 업데이트문 반복
cs



2.  쿼리에서 select 한 값(5만건)을 한번에 바로 update하기


1. 같은 행사번호에 10만원~20만원 사이 구매한 고객이 5만명이고 이 5만명이 각각 다른 응모자참여번호가 들어갈때

2. 응모자 5만명을 모두 당첨처리를 하기 위해선

3. 5만명에 대한 각각의 응모자참여번호를 서브쿼리로 구해와 

4. 응모자참여테이블의 응모자참여번호에 해당하는 당첨상태 코드를 update 시킨다.

5. select한 값을 한번의 쿼리 수행을 통해 5만건 모두 update 시키고 있다.

6. select한 값을 update치면서 DB Lock이 걸릴수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
-- 1. 같은 행사번호에 10만원~20만원 사이 구매한 고객이 5만명이고 이 5만명이 각각 다른 응모자참여번호가 들어갈때
-- 2. 응모자 5만명을 모두 당첨처리를 하기 위해선
-- 3. 5만명에 대한 각각의 응모자참여번호를 서브쿼리로 구해와 
-- 4. 응모자참여테이블의 응모자참여번호에 해당하는 당첨상태 코드를 update 시킨다.    
-- 5. select한 값을 한번의 쿼리를 수행을 통해 5만건 모두 update 시키고 있다.
UPDATE  pr_evnt_tkpt a -- 응모참여 테이블
         INNER JOIN (SELECT b.EVNT_PTCP_NO
                          , SUM(b.PUR_RCGN_AMT) as PUR_RCGN_AMT
                       FROM pr_evnt_ptcp_ord b -- 응모참여 주문테이블
                      WHERE b.CMPN_NO = '1'
                      GROUP BY b.EVNT_PTCP_NO, b.CMPN_NO
                     HAVING SUM(b.PUR_RCGN_AMT) >= 100000
                        AND SUM(b.PUR_RCGN_AMT) < 200000 
         ) b
            ON a.EVNT_PTCP_NO = b.EVNT_PTCP_NO
           SET a.EVNT_TKPT_STAT_CD = '10'        -- 당첨확정
             , a.MODR_ID = 'shlee0882'
         WHERE a.CMPN_NO = '2'
cs


+ Recent posts