loop를이용한 select update질문 0 6 3,004

by 이제시작이야 [PL/SQL] loof update index [2020.06.04 15:18:40]


지금 제가 할려는 작업이 table1과 table2의 name,name2의 컬럼값이 같을경우 table1에id컬럼에 table2의 id컬럼값을 update해줄려고합니다.

그래서 원쿼리로 작업을 해봤는데

update table1 a
set id = (select distinct id
                  from table2 b
                  where a.name=b.name and a.name2=b.name2)

각테이블마다 데이터가 몇십만건씩 있어서 그런지 40분동안 쿼리수행을해도 update가 완료되지않아

table2의 name컬럼에다가 index를 생성후 loop를돌려봤으나 역시 40분이 지나도록 update가 완료되지않았습니다.

begin

for i in( select id,name,name2
               from table2 )
loop
update table1 
set id=i.id
where name = i.name and name2=i.name2
;

commit;

end loop;

end;  

 이경우 table2에 index를 생성하였으니 table1으로 loop를 돌려 table2의 값을 찾으면 된다고하는데 쿼리를 어떻게 수정해야되는지 감이 안와서

고수님들의 조언을 구해봅니다...

by ㅇㅇ준 [2020.06.04 15:58:39]

최종 질문과는 크게 상관없으나 ..

업데이트 쿼리에 문제가 있어보입니다.

로직상 검토가 필요할것같네요.

1. pk 구조를 보셔야겠지만 distinct를 걸었다는건 id가 중복되어 조회될수 있겠다 싶습니다. subquery의 결과값이 다수의 row가 출력될경우 해당 구문은 오류가 나옵니다.

2. table2, table1 의 name, name2가 같은경우 update를 table2의 값으로 업데이트 합니다. 현재의 table1, table2의 id가 같아도 update할 필요가 있을까요.

3. table1의 name, name2가 table2에 없을 때 table1의 id는 null로 업데이트 하겠습니다.


by 이제시작이야 [2020.06.04 16:05:48]

1.id는 distinct id 만으로도 중복이 안나왔습니다.

2,3. table1의 id값은 전부 null입니다.


by ㅇㅇ준 [2020.06.04 16:23:37]

table2의 데이터는 전체를 다 가지고 오니 index는 소용없다고 보여집니다.

table1의 name, name2 로 인덱스 구성하시면 해당 루핑방식 업데이트에서는 효과를 볼수있습니다.

인덱스 생성시 기존 수행중인 다른쿼리의 실행계획 변경등에 영향을 미칠수있으니 검토후 생성하시는게 좋겠습니다


by 이제시작이야 [2020.06.04 16:32:32]

허..

table2의 name||name2값이 중복이 있었네요

제거후 업데이트 실행해봐야겠습니다.

index는 검토해보니 제거하고 진행하는게 나을것같네요.

친철한 답변 감사드립니다^^


by 마농 [2020.06.04 16:43:16]

t2 에 인덱스를 걸었다면? 변경전 쿼리를 이용하시면 되고요
t1 에 인덱스를 걸었다면? 변경후 쿼리를 이용하시면 됩니다.
인덱스는 name, name2 결합인덱스로 만드세요.
중복 값이 있다면? 쿼리 개선이 좀 필요해 보입니다.


by 이제시작이야 [2020.06.04 16:57:28]

인덱스에대해서 반대로 생각하고 있었군요;;

중복값을 제거했는데도 쿼리수행시간이 30분이 다되어가네요.

40분이 지난다면 마농님 말씀대로 결합인덱스로 만들고 실행해봐야겠네요.

언제나 친절한답변 감사드립니다^^

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입