[SQL] Query 작성시 유의할 점
1. 필요도 없는 아우터 조인을 남발하지 말기
2. 한번에 가져올 수 잇는 쿼리는 UNION ALL로 묶어서 가져온다음 로직단에서 처리
- 메모리와 Disk간 I/O가 속도에 영향을 크게 줌
3. Join SQL의 경우 드라이빙 순서를 맞춤
- NL-Join시 2개 테이블중 Size가 작은 것이 드라이빙는 것이 아니라.. 인덱스가 없는 테이블을 먼저 드라이빙
- 복잡한 조건문이 포함될 경우.. 처리량이 작은 순서
4. 인덱스 제대로 탈 수 있도록 조건 주기
- WHERE user_id > '' 같이 값이 안들어와도 인덱스를 타는 경우 속도가 더 잘 나올 수 있는 경우
위와 같이 트릭조건을 걸어 옵티마이저가 인덱스를 선택 할 수 있도록 도와 줄 수 있음
- 인덱스가 걸린 컬럼을 가공하지 않기
where Substr(User_id, 1, 3) = '123' ----> where User_id like '123%' 으로 처리
5. 데이터 타입은 필요한 만큼만 잡아주기
- 컬럼 길이의 편차가 심한 경우, NULL 로 입력되는 경우가 많은 경우 VARCHAR2 사용
- 무조건 넉넉하게 잡기보다는 들어갈 내용에 알맞게 잡아주는게 좋습니다.
varchar2(4000) 으로 잡아 놓았다가 텍스트 다운로드할 필요가 있을 때나 화면에 디스플레이 시켜야 할 필요가 있을 때
도대체 자리를 몇자리나 잡아야 하는지 고민될 수 있음
- null은 말 그대로 값이 없음을 의미하기 때문에 물리적으로도 공간을 따로 할당하진 않습니다.
하지만 null값에 접근하기 위해서는 4바이트 정도의 주소공간은 필요합니다.
6. char(5) 보다는 varchar2(5)를 쓰기
- Space가 추가되는 char 형이 Scan할 데이터가 더 많아져서 성능이 떨어짐
- 한바이트의 칼럼이라도 오라클에서는 char 보다는 varchar2 가 권장됨
- 지금은 varchar라고 선언하면 내부에서 varchar2로 변환하는 것으로 알고 있습니다.
tip)
1. indentity를 가진다면 Integer로 만들어야 하고, 순수 값의 의미라면 int를 쓰는 것이 맞다.
ex.)
PK, FK의 시퀀스값(ID) : Integer
나이, 점수 (int는 원시 자료형) : int
2. DB에서 null이 반드시 필요한 경우 Integer를 사용한다. int로는 null이 불가능하다.
7. 부정형 조건 쓰지 말기
- is not null, not exists 등
- 애초에 null이 들어가는 경우가 문제가 있다면 null 안들어가게 default 값 잡아주기
8. select 시 * 쓰지말고 필요 컬럼만 적어 주기
- 블럭단위로 퍼올리는데 쓸데없이 I/O 엑세스만 더 늘리지 말기
- 내부적으로는 프로그램에서 사용안하는 컬럼들까지 I/O를 통해 통신됨
9. 테이블 설계할때 업무 조회시 자주 발생하는 경우와 조건 컬럼 분석해서 인덱스 잡기
- 시스템 구축 초기에 화면정의서를 보고 사용 패턴을 분석하여 인덱스를 설계
10. distinct 보다 group by 쓰기
- distinct 가 RDB체계에서는 temp space를 사용하며 그안에 임시로 저장하고 정렬하는 방식이라
과부하가 많이 걸리기 때문에 group by를 사용
- distinct 는 일단 원하는 select문들이 나타는데 중복이면 없애는 방식
group by 는 조인을 했을때 양 그룹중 같은 필드를 한대 묶은 방식
11. if else로 쿼리를 여러개 만들어 하나 실행하는 것 보다 SQL에 상수를 이용해 처리하는게 더 퍼포먼스가 좋음
SELECT ...
FROM ...
WHERE '1' = '상수'
Union All
SELECT ...
FROM ...
WHERE '2' = '상수'