데이터 성능 측정과 실행계획 질문드립니다. 0 2 1,798

by 김태성 [Oracle 기초] [2015.10.08 11:44:51]


공부로 자바랑 오라클을 사용해서 진짜 간단한 재고관리를 하나 만들고 있습니다.

대량의 데이터를 넣어서 성능튜닝해보는게 목적입니다.

일단 이해를 돕기위해 간단히 설명하자면 두개의 테이블이 있습니다.

하나는 제품구분별로 창고에 몇개, 진열중인게 몇개인지 넣는 테이블입니다.(STOCK_STATE)
PRODUCT_CODE, STORAGE, DISPLAY
위와같은 구성입니다.

또 하나는 모든 제품 하나하나 에 대한 정보가 들어있는 테이블입니다(ALL_PRODUCT)
PRODUCT_NO(시퀀스,중복불가), PRODUCT_CODE, STORAGE_FLG(창고에있는지, 진열중인지), 구매날자

대략이지만 위와같은 두개의 테이블이 있고, 예를들어 스쿠류바를 30개 구매했을시 아래와같은 처리를 합니다
STOCK_STATE의 PRODUCT_CODE가 스쿠류바인 녀석의 STORAGE에 30을 +해서 업데이트 합니다.

그 후에 ALL_PRODUCT테이블에 PRODUCT_CODE를 스쿠류바로 해서 30번의 INSERT를 합니다.

즉 ALL_PRODUCT는 구매를 거듭할수록 데이터수가 늘어납니다.

여기서 성능 측정을 위해 제품들을 종류별로 구매신청해서 700만건정도 ALL_PRODUCT에 INSERT한 상태입니다.

여기서부터가 본격적인 질문인데요.

먼저 어떤 테이블에도 프라이머리키나 인덱스는 설정하지 않고있습니다. 이후에 인덱스 설정 후 성능을 비교해보기 위함입니다.

현제 ALL_PRODUCT를 SELECT해보면 대략 16~20초정도의 시간이 걸립니다.
근데 실행계획을 보면 풀스캔해서 코스트가2밖에 안되더군요. 얼마전에 책보고 실행 계획으로 인덱스가 사용되고 있는지 확인하는 법과 코스트가 작을수록 성능이
좋다고 생각했는데...데이터가 100만건으로 1초만에 검색할떄랑 700만건으로 20초걸릴때의 코스트가 똑같이 2라는게 의문이 들었습니다.

코스트로 성능을 판단하는게 아닌건가?? 라는 의문이 들어서 이부분에대해 질문드리고 싶습니다.
검색은 조건 없이도 검색해보고, 조건 범위를 작개해서도 해보고 넓게해서도 해봤으나 똑같았습니다.

여기서 음 좀 이상하네...라고 생각해서 PRODUCT_NO에 인덱스를 붙여봤습니다.
그리고 검색조건에 PRODUCT_NO = 1000000으로 검색을 해봤는데....

실행속도가 빨라진 것 같기도 하고 기분탓인것 같기도 해서 확실한 성능 차이를 보기위해 실행계획을 봤는데.
인덱스를 사용하지않고 풀스캔 하고 있는 것입니다....

왜 인덱스가 사용되고 있지 않은지 잘 모르겠습니다...인덱스를 붙이긴했는데 지금 책이 없어서 확인핤가 없지만 혹시 실행계획을 넘겨주거나 하는
그걸 하지않으면 테이블에 인덱스를 붙이는 것 만으로는 인덱스를 사용하지 않는건가요?? 이게 두번쨰 질문입니다.

마지막 질문으로 테이블 설계인데요.
ALL_PRODUCT는 하나하나 다른 제품이기 때문에 PRODUCT_NO에 일의제약을 걸고싶습니다.
그래서 PRIMARYKEY로 설정할 생각인데요. 신경쓰이는건
주키로 설정하면 인덱스가 기본적으로 붙는것으로 알고있습니다. 근데 이 ALL_PRODUCT는 검색보다는 추가, 삭제, 갱신처리가 많습니다.
인덱스가 붙어있는 테이블은 추가, 삭제, 갱신시에는 오히려 처리가 느려진다고 알 고 있는데...이럴 경우 보통 어떻게 하시나요?
PRODUCT_NO를 주 키로 설정하지 않고, 그냥 중복불가만 걸어주는게 일반적일까요??

질문이 길어젔는데 도움 주시면 감사하겠습니다 ^^;

by 마농 [2015.10.13 13:36:33]

1. 비용이 동일한 이유는?
  - 아마도 테이블의 통계정보가 부정확하기 때문일 듯.
  - 비용산정은 통계정보를 바탕으로 합니다.
2, 인덱스를 안타는 이유는?
  - 아마도 해당 항목의 타입이 문자가 아닐까 생각됨.
  - 문자 컬럼에 숫자 조건을 주면 컬럼을 숫자로 변형시켜 비교하게 되며
  - 컬럼에 변형이 가해지게 되면 인덱스를 타지 못합니다.
3. 인덱스가 있으면 DML 이 늦어지므로 만들지 말자?
  - 말도 안되는 소리입니다.
  - 한건에 대한 입력처리시 테이블과 인덱스를 두번 입력해서 늦은 것은 사실이지만
    사용자가 느낄수 있는 수준의 속도차가 아닙니다.
  - 여러건에 대해서 처리한다면 늦어질수도 있겠으나
    무지막지하게 많은 건이 아니라면.. 이또한 속도문제는 없습니다.
  - 무지막지하게 많은 건을 한번에 입력한다면?
    이는 별도 계획을 세워서 하면 됩니다.(인덱스 제거 > 병렬처리 입력 > 인덱스 재생성)
  - 입력이 아닌 갱신이나, 삭제시에는 오히려 인덱스가 있어야 빠릅니다.
    갱신하고자 하는 한건을 빨리 찾아야 하니까요.
  - PK 대신 중복불가만 하고자 한다면?
    중복불가 또한 인덱스가 자동으로 만들어 집니다.


by 김태성 [2015.10.13 15:49:43]

마농님 매번 놀랄만큼 알기쉽고 전문적인 답변에 감사합니다. 이번에도 정말 놀랍네요 ;;

답변이 안달려서 지식인에 질문해서 통계 정보가 생성되지 않은게 원인이란걸 알고 통계정보를 생성하므로써 인덱스가 타지도록 해결이 되었는데. 그 후 몇가지 의문이 있어서 다시 질문하러 왔다가 달린 답변내용 보고 깜짝 놀랐습니다 ㅎㅎ

질문하려던 내용 중 하나가 인덱스가 달린 항목이 문자열 항목인데 조건절에 문자열이 아닌 숫자형식으로 작성하면 인덱스를 안타길래 이부분에 대해서 질문 하려 했더니 달아주신 2번답변에 그 내용이 들어있어서 깔끔하게 이해됐고 ^^

또 하나, 질문 했던 추가, 삭제, 업데이트는 인덱스를 붙임에의해 느려질 수 있으므로 추가,삭제,수정이 잦은 테이블에 인덱스를 붙일떄는 주의해야 할 것 이라는 질문에대해 실제로 확인해 봤더니, 업데이트 삭제의 경우 인덱스가 붙은 조건절을 붙여줌으로써 삭제,수정이 우월하게 빨라젔고 삽입시에도 1000만건이 넘는 데이터가 있음에도 전혀 속도적으로 느리다고 생각되지 않아서 확인할겸 구루비에 다시 질문드리려고 했는데 3번에서 너무 명쾌하게 알려주시고 있네요 ^^. 정말 감사합니다 많은 공부되었습니다.

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