지금까지 십여년 가까이 전산쟁이 생활하면서 개발자들이 많이 저지르는 SQL miss-사용법에 대해 한번 정리 해보고자 한다. 한마디로 성능 저하의 원인이 되는 것들이다.
특히 이런 녀석들은 데이터량이 작을때는 문제가 안되다가 일정 용량 넘어가면 그때부터 문제가 되는 녀석들이다.

따라서, 실행계획을 계속 모니터링 하면서 일정 시간 이상의 SQL문은 튜닝해주자.

1. Index를 생성하지 않은 컬럼에 Where 조건 주는 경우
조건 : T1이라는 Table은 C1과 C2 컬럼이 있다.
SQL : select C1 from T1 where C2 = '1'
이경우 CPU 부하가 무지막지하게 올라간다. C2에 Index가 걸려 있는지 확인하여 안걸려 있다면 걸어주도록 하자.

2. Database Table간에 중복되는 값이 들어가 있는 경우
조건 : T1에 C1과 C2가 있고 T2에는 C3와 C4, C5가 있는데 C1과 C3는 PK/FK 관계이다. C2와 C5는 사실상 같은 내용의 컬럼이다.
이경우는 성능보다는 데이터 무결성에 문제가 되기도 한다. 또한 T1과 T2를 정규화 시키지 않음으로 해서 결과적으로 update 1번이면 되는 것을 2번하게 만드는 것때문에 불합리한 사용법중 하나이다.

3. Order by 명령
조건 : T1에 C1과 C2가 있다.
SQL : select C1 from T1 order by C2
흔히 사용하는 Query문이다. 문제가 되는 이유는 조건 없이 Full Sorting 하고 있다는 점이다.
이런 경우는 반드시 where 조건을 줘서 뽑아온 부분만 Order by 를 하도록 하자.
(간단한 사례 100,000건의 데이터 남녀 구분의 데이터 중에 정작 쓰는건 남자라고하면 Where 조건을 주게되면 50,000건만 Sorting하게 된다.)

4. Join 명령
조건 : T1에 C1과 C2가 있고 T2에 C3와 C4가 있다.
SQL : select T1.C1, T1, C2, T2, C4 from T1 join T2 on T1.C1=T2.C3 where T1.C1 = '1'
주로 사용하는 방식의 Join명령이다. 하지만 이것도 데이터의 수가 많으면 문제가 된다.
T1의 C1을 기준으로 T2의 C3와 매칭시켜 뽑아 오는 Query문인데 이런 경우는 이렇게 처음 부터 만들면 나중에 데이터가 많아지더라도 크게 문제가 되지 않는다.
select VT1.C1, VT2.C2, T2.C4 from (select C1, C2 from T1 where C1='1') VT1 join T2 on VT1=T2
Full scan 이 일어날 만한 명령을 사전에 차단해버리는 방법이다.

5. Hint 를 주지 않는 경우
조건 : T1에는 C1, C2, C3가 있고 C1과 C2에 각각 Index1과 Index2가 걸려 있다.
SQL : select C1, C2 from T1 where C2 = '1'
이런 경우는 특정 인덱스를 타라고 선언해주는 쪽이 나중에 성능 문제가 발생하지 않을 소지가 높다.
다시말해 이렇게 바꾸도록 하자
MSSQL : select C1, C2 from T1 with (INDEX (index2)) where C2='1'
Oracle : select /*+INDEX(index2) */ C1, C2 from T1 where C2='1'

보통 CPU에 과부하 걸린다고 해서 나가서 보면 이런 문제들이다.
처음 개발할때 부터 조금만 신경 쓰면 나중에 문제가 발생하지 않을 일을 하고 있다는것이 매우 아쉽다고나 할까?

그리고나서는 꼭하는 말들이 이러하다.
MS-SQL이라서... MySQL이라서...
ORACLE이 사실 하드웨어 스팩상 가장 빵빵하기때문에 이러한 실수를 조금 가려주기도 한다.
그러나 이런 문제들은 지아무리 오라클이 와도 조금 지나면 재발되는 문제이다.

나중에 땀 삐질 삐질 흘리지 말고 지금부터라도 잘 잡도록 하자
2009/08/20 11:41 2009/08/20 11:41

트랙백 주소 :: 이 글에는 트랙백을 보낼 수 없습니다