중복 데이터 삭제 질문입니다. 0 2 3,602

by 콩이 [DB 모델링/설계] 성능 테이블 속도 [2012.11.16 16:32:59]


안녕하세요. 중복 관련해서 질문을 드립니다...

테이블 구조는 아래와 같습니다.

'그룹' 테이블
번호 | 그룹명 | 등록자ID | 날짜
'그룹상세' 테이블(데이터 600만건)
번호 | 부모번호 | 성명 | 핸드폰 | 이메일 | 팩스 | 등록자ID | 날짜

'그룹' 테이블은 T_ADDR_GROUP
'그룹상세' 테이블은 T_ADDR_DETAIL 입니다.

인덱스 정보는 아래와 같습니다.
T_ADDR_GROUP (NO) *PK
T_ADDR_GROUP01 (NAME, NO)
T_ADDR_DETAIL (NO) *PK
T_ADDR_DETAIL01 (USER_ID, NO, PARENT_NO)
T_ADDR_DETAIL02 (USER_ID, NAME, PARENT_NO)
T_ADDR_DETAIL03 (PARENT_NO)


우선 중복된 데이터를 중복된 수와 함께 보여주는 리스트에서는 다음과 같은 쿼리를 사용했습니다.
이름 | 핸드폰 | 중복수
가져오는 수를 적게 하기 위해 ROWNUM으로 페이징 했습니다. 리스트 쿼리 관련해서 더 좋은 방법이 있으면
조언 부탁드려요.

카운트
SELECT COUNT(*) AS CNT FROM (     SELECT NAME, hp, fax, ROW_NUMBER() OVER(PARTITION BY hp ORDER BY hp) ct     FROM T_ADDR_DETAIL WHERE parent_no IN (15) AND  user_id = 'lee9982' AND hp IS NOT NULL ) WHERE ct >1 

리스트
   SELECT * FROM (
SELECT ROWNUM AS RNUM, A.* FROM (
SELECT NAME, hp, fax, ROW_NUMBER() OVER(PARTITION BY hp ORDER BY hp) cnt 
    FROM T_ADDR_DETAIL WHERE parent_no IN (15) AND  user_id = 'lee9982' AND hp IS NOT NULL 
            ORDER BY cnt desc
) A WHERE ROWNUM <= 10 AND cnt > 1
  ) WHERE RNUM >=6
실행계획
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|Operation                                 |        Object Name        | Rows | Bytes | Cost | Object Node | In/Out | PStart | PStop | Access Predicates |             Filter Predicates            |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SELECT STATEMENT Optimizer Mode=ALL_ROWS |                           |   10 |   610 |   45 |             |        |        |       |                   |                                          |
|  VIEW                                    |                           |   10 |   610 |   45 |             |        |        |       |                   |                                "RNUM">=6 |
|   COUNT STOPKEY                          |                           |      |       |      |             |        |        |       |                   |                               ROWNUM<=10 |
|    VIEW                                  |                           |  2 K | 104 K |   45 |             |        |        |       |                   |                                  "CNT">1 |
|     SORT ORDER BY                        |                           |  2 K |  74 K |   45 |             |        |        |       |                   |                                          |
|      WINDOW SORT                         |                           |  2 K |  74 K |   45 |             |        |        |       |                   |                                          |
|       TABLE ACCESS BY INDEX ROWID        |T_ADDR_DETAIL       |  2 K |  74 K |   43 |             |        |        |       |                   | "USER_ID"='lee9982' AND "HP" IS NOT NULL |
|        INDEX RANGE SCAN                  |IN_T_ADDR_DETAIL03  |  3 K |       |   10 |             |        |        |       |    "PARENT_NO"=15 |                                          |

위와 같습니다.


그리고 두번째 문제는 중복된 데이터들을 DELETE 하는 부분인데요,
삭제의 조건이 중복된 데이터를 모두 삭제하는 조건이구요, 두번째 조건은
선택된 그룹번호에 대한 데이터들을 삭제하는 조건입니다.

쿼리
DELETE FROM T_ADDR_DETAIL a
WHERE ROWID > (SELECT MIN(ROWID) FROM T_ADDR_DETAIL B 
WHERE A.HP = B.HP AND B.PARENT_NO = 15)

실행계획
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|Operation                                 |        Object Name        | Rows | Bytes | Cost | Object Node | In/Out | PStart | PStop | Access Predicates |             Filter Predicates            |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SELECT STATEMENT Optimizer Mode=ALL_ROWS |                           |   10 |   610 |   45 |             |        |        |       |                   |                                          |
|  VIEW                                    |                           |   10 |   610 |   45 |             |        |        |       |                   |                                "RNUM">=6 |
|   COUNT STOPKEY                          |                           |      |       |      |             |        |        |       |                   |                               ROWNUM<=10 |
|    VIEW                                  |                           |  2 K | 104 K |   45 |             |        |        |       |                   |                                  "CNT">1 |
|     SORT ORDER BY                        |                           |  2 K |  74 K |   45 |             |        |        |       |                   |                                          |
|      WINDOW SORT                         |                           |  2 K |  74 K |   45 |             |        |        |       |                   |                                          |
|       TABLE ACCESS BY INDEX ROWID        |T_ADDR_DETAIL       |  2 K |  74 K |   43 |             |        |        |       |                   | "USER_ID"='lee9982' AND "HP" IS NOT NULL |
|        INDEX RANGE SCAN                  |IN_T_ADDR_DETAIL03  |  3 K |       |   10 |             |        |        |       |    "PARENT_NO"=15 |                                          |

위와 같이 합니다. 삭제엔 5초 정도 걸립니다. 그런데 문제는 15번 그룹에 속한 데이터는 8761건인데
툴에서 삭제(Commit 안하고)해보면 Delete record가 11192로 나옵니다. 혹시 쿼리에 문제가 있나요?

고수님들의 많은 조언 부탁드립니다.




by 마농 [2012.11.16 17:57:48]

삭제건수가 예상보다 많은 이유는 같은 핸드폰 번호가 다른 그룹에 있을수도 있기 때분입니다.
이 경우 다른 그룹에 속한 데이터도 삭제 되겠네요.
a.parent_no = 15 조건을 메인 조건으로 추가하세요.


by 손님 [2012.11.19 10:08:22]
예 마농님 대단히 감사합니다. 메인조건으로 해봐야겠네요. ^^
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입