Oracle max와 rownum 속도 차이 0 6 8,232

by 양갱양갱 [Oracle 기초] max rownum [2015.03.05 13:56:01]


안녕하세요. 대용량 디비를 처음 접하는 사람입니다.(하지만 데이터가 그렇게 대용량이지 않습니다.,)

A라는 테이블(총 row수 대략 300만건)에 데이터가 있는지 없는지 조회하는 쿼리입니다.

오늘 날짜를 입력하면 오늘자가 column6 에 대입되어 오늘 이전에 중복된 데이터가 있으면 insert안하고 없으면 집계테이블(B)에 insert하는 로직입니다.

사실 아래 로직에서 cnt의 의미는 과거 중복된 데이터 존재여부 입니다.

select count(1) cnt from A c

where column1 = '구분' and column2='종료일자' and column3='파일구분' and column4='영업소' and column5='영업소지역' and column6 < '입력날자' and column7 ='파일명'

해당 카운터로 조회해서 데이터가 없으면 다른 B테이블(A테이블의 집계)에 insert하는 로직입니다.

A테이블의 모든 값은 널을 허용하지 않음으로 데이터가 무조건 다 있습니다.

A테이블의 index는

IX_A_01 : column1 , column6

IX_A_02 : column1 , column2 , column4, column5

PK_A    : column1 , column2 ,column7, column8(시퀀스)

PK_A에서 column1 , column2 ,column7컬럼은 중복된 데이터가 마구 들어오고 대신데 column8에서 똑같은 데이터가 들어오면 column8 에 +1 함.

아래 로직이 느린것 같아 튜닝을 하려고

기본 로직에 index가 IX_A_01으로 타서

{

select /*+ index(A PK_A) count(1) cnt from A c

where column1 = '구분' and column2='종료일자' and column3='파일구분' and column4='영업소' and column5='영업소지역' and column6 < '입력날자' and column7 ='파일명'

and rownum =1

}

으로 바꾸었는데 A테이블에 데이터가 많은지 몰라도 크게 속도 차이가 나지 않네요.

IX_A_01 탈때는  cost가 0 cardinality 37

PK_A    탈때는  cost가 0  cardinality 82

입니다.

정말로 대용량 데이터가 아니라서 두 쿼리 속도차이를 확인할 수 없는건가요??? ㅠ

아니면 두 쿼리 속도 차이를 확인할 수 있는 방법이 있나요?

 

2) plan떴을때  1쿼리는 cost 1 cardinality 30

                      2쿼리는 cost 0 cardinality 60 일때 어떤게 수행속도가 더 좋을까요?

 

많은 답변 부탁드릴께요~

 

by jkson [2015.03.05 14:13:11]

분포도가 어떤지 모르겠지만 쿼리로만 보아서는 column1, column2, column7까지 조건이 걸리는 pk_a 인덱스가 나아보이는데... 혹시 종료일자가 중복되는 건이 엄청 많나요? 확실하게 확인하려면 trace 떠 봐야 정확하겠죠. 아.. 그리고 오타겠지만.. select /*+ index(A PK_A) count(1) cnt from A c => select /*+ index(C PK_A) */ count(1) cnt from A C 겠죠?


by 부쉬맨 [2015.03.05 15:29:14]

1번쿼리와 2번쿼리의 갯수(count의 결과) 값이 기초자료로 필요해보입니다.

내용을 보았을때 유주해본다면 위의 내용에 대해서는 결과값은

크게 차이가 나보이지는 않겠네요.

차이가 나지않는다면 그러한 이유로 때문입니다.

속도가 얼마나 나오는지에 대한 결과값도 알려주셔야될꺼같네요.

대상 인덱스만 나온다면 그렇게 느려보이지는 않아요.

단순 데이터가 있는지 없는지 판단을 하는용도라면 min, max 를 사용하여 index_desc , index_asc 힌트로 성능향상을 불러올수 있고요.

또한 rownum =1 으로 판단만 하게 할 수 있겠고요.

아님 데이터가 정말 많아서 인덱스가 무의미하다면

index_ffs 스캔으로 db_block_multi 로 향상을 불러올수 있습니다.


by 양갱양갱 [2015.03.05 17:04:32]

프로그램 절차가 A라는 테이블에 평균2000건(오늘 들어온 데이터 row수)을 가지고와서 A에 중복된값(오늘 이전의 row 300만건)이 있나 없나 확인하는거예요.

A라는 테이블에 중복된 데이터인지 확인하는 방법은 A테이블은 데이터가 들어오면 히스토리 성격의 테이블이기 때문에 column8(시퀄스), 등록한 날짜 만 값이 달라지게 됩니다.(나머지 컬럼 데이터는 똑같습니다. 그리고 널 허용 안하고요)

그리서 A라는 테이블에 오늘날짜를 검색해서 (평균 2000건) 오늘이전날짜에 중복된 데이터가 있는지 확인하여 있으면 insert안하고 없으면 라는 B테이블(집계용 테이블)에 cont(수집건수)+1 이렇게 update합니다.

1번 쿼리의 자료수는 검색조건에 따라서 count값이 달라지는것 같아요

2번 쿼리의 자료수도 마찬가지이고요(안에 대입하는 상수는 바인드변수로 설정되었어요=pro*c에서 A테이블에서 검색해서 A테이블로 where 절 조건에 상수로 넣어줌)

그러기 때문에 각각 조건에 따라 count의 결과값이 달라집니다.

1번 쿼리 처음실행하면 7초

2번 쿼리 처음실행하면 12초

1번 쿼리 2번째 실행하면 캐쉬 메모리 적제되어 5초

2번 쿼리 2번째 실행하면 캐쉬 메노리에 적재되어 6초 입니다.

 

제가 궁금한거는 지금 운영에 1번 쿼리로 돌고 있는데 총 처리하는 건수가 4천건 밖에 안되는데 1시간 30분이 걸리고 있습니다. 총 배치에서 도는 select문이 4개밖에 안되는데 plan뜨면 나머지는 옵티마이져가 잘 인텍스를 타는데 이것만 잘못타는것 같은데 개발에서 테스트하면 속도 차이가 많이 나지 않아서 궁금해서요. 개발서버나 운영서버는 당연히 차이가 나겠지만 인덱스를 명시했을때하고 명시하지 않았을때 차이가 너무 안나서 왜 그런지 궁금하네요.

그리고 너무 궁금했는데 빠른 답변 감사해요

 

 


by 부쉬맨 [2015.03.05 17:21:53]

인덱스를 태워서 문제가 생긴거라면

인덱스를 타지않게 /*+ FULL(테이블) */ 형태로 전체 대상을 읽도록 수정하여서 테스트 진행해보세요.

차이가나는걸 정확히 확인을 위해서는 플랜정보가 필요해보입니다.

개발 플랜, 운영 플랜


by 마농 [2015.03.06 10:17:07]

반복적으로 사용되어야 하는 부분이라면?
인덱스 개선이 필요합니다.
1,2,3,4,5,7,6 으로 구성된 인덱스를 생성하세요.


by 필상 [2015.03.06 10:18:27]

PLAN 상에서 하기의 PK_A 이 인텍스가 나타나는지 확인이 필요할 거로 보입니다.

PK INDEX를 경유했는데 위에 말씀하신 7- 12초대의 응답이 이해가 되질 않네요..(300만건에 대해)

select /*+ index(A PK_A) count(1) cnt from A c

where column1 = '구분' and column2='종료일자' and column3='파일구분' and column4='영업소' and column5='영업소지역' and column6 < '입력날자' and column7 ='파일명' and rownum =1

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