SlideShare a Scribd company logo
1 of 26
개발자가 흔히 실수하는 SQL 7가지
2014 자바카페 SQL 동영상 스터디 이정근
cjred77@gmail.com
1
2014 자바카페 SQL 동영상 스터디 이정근
1. SQL 파싱 순서
2. 인덱스 스캔, 풀스캔
3. 무조건 인덱스 많이
4. 조인을 사용하면 성능이 떨어진다?
5. count(*) > 0
6. 내림차순 인덱스 와 힌트절
7. LIKE BETWEEN, <>, IN
2
2014 자바카페 SQL 동영상 스터디 이정근
SQL 파싱 순서
SELECT * FROM BIG_EMP
WHERE MGR=‘7698’ AND DEPTNO=’60’;
직원테이블(EMP) 의 총 사원수(레코드 개수) 28955명
메니져(MGR) 가 7698인 사원수 10,319명
부서(DEPTNO) 가 60 인 사원수 1263명
3
MGR
7698
etc
DEPTNO
60
etc
2014 자바카페 SQL 동영상 스터디 이정근
SQL 파싱 순서
COST 기반 옵티마이져 인 경우 옵티마이져가 알아서 순서를 정함.
(대부분의 경우 COST 기반 옵티마이져를 사용)
RULE 기반 옵티마이져인 경우 이거나 RULE 을 사용하도록 힌트를 사용 하는 경우
1. 가장 나중에 생성한 인덱스가 있는 컬럼부터 파싱
2. 같은 경우 AND 는 WHERE 절에 가장 가까운 조건부터 뒤에서 부터 ,
OR 는 WHERE 절의 가장 오른쪽부터 파싱
DEPTNO=‘60' AND MGR=‘7698'; 앞 --> 뒤
DEPTNO=‘60' OR MGR=‘7698'; ; 앞 <-- 뒤
4
2014 자바카페 SQL 동영상 스터디 이정근
SQL 파싱 순서
5
MGR=‘7698' AND DEPTNO=‘60'; 앞 --> 뒤 DEPTNO=‘60' AND MGR=‘7698'; 앞 --> 뒤
2014 자바카페 SQL 동영상 스터디 이정근
SQL 파싱 순서
6
DEPTNO=‘60' OR MGR=‘7698'; 앞 <-- 뒤
2014 자바카페 SQL 동영상 스터디 이정근
SQL 파싱 순서
A : 일반적(COST 기반 옵티마이져) 으
로 WHERE 절 컬럼순서에 상관없음
7
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
SELECT SAL FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN’;
8
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
Single Block I/O (랜덤 액세스)
• 인덱스를 사용하여 검색(인덱스 스캔)을 하게 되면 한번
의 I/O 요청에 한 블록씩 데이터를 읽는다.
Multi Block I/O
• 전체 데이블 검색(풀 스캔)은 데이터를 읽을 때 한번의
I/O 요청으로 여러 블록을 한꺼번에 읽는다.
9
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
Single Block I/O
1. 인덱스 테이블에서 조건절 검색 MGR=‘7698'
2. ROWID 로 테이블 검색 (1만 ROW , 1만회 I/O)
3. 조건절 검색 ( JOB='SALESMAN')
Multi Block I/O
1. 3만 / 150 = 2백회 IO
2. 조건절 검색 ( JOB=‘SALESMAN')
10
10만 I/O
2천 I/O
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
풀 스캔을 유도하는 방법
• 인덱스가 걸린 컬럼을 가공
SELECT SAL FROM BIG_EMP
WHERE MGR || ‘’ ='7698‘ AND JOB='SALESMAN';
• 힌트를 사용
SELECT /*+ FULL(EMP) */
SAL FROM BIG_EMP
WHERE MGR='7698' AND JOB='SALESMAN';
11
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
12
2014 자바카페 SQL 동영상 스터디 이정근
인덱스 스캔, 풀 스캔
A : 인덱스컬럼의 조건이 대부분의 경
우에 포함되는 경우 풀 스캔이 더 성능
이 좋을 수 있음
13
2014 자바카페 SQL 동영상 스터디 이정근
무조건 인덱스 많이
SELECT SAL FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN’;
• 인덱스를 만들거나 수정시 DB 성능 지연 발생
• 분포도가 좋지 않은 컬럼에 인덱스를 생성하더라도 성능에 영향이
적음.
– 대부분의 LOCATION 컬럼값이 'SEOUL' 인 경우 오히려 Full Scan
이 유리
• INSERT, UPDATE, DELETE 시에 성능 저하
14
2014 자바카페 SQL 동영상 스터디 이정근
무조건 인덱스 많이
A : 인덱스를 꼭 필요한 경우에만 추가
해야 한다.
15
2014 자바카페 SQL 동영상 스터디 이정근
조인을 사용하면 성능이 떨어진다?
A : 정규화를 하면 저장공간 및 I/O 부하가 줄어듬
16
사원번호 (8)
이름 (10)
생년월일 (8)
입사일 (8)
직급 (8)
연봉 (4)
부서명 (12)
부서사업장주소 (100)
부서장이름 (10)
40만 레코드 X 168 Byte
= 67,200,000 Byte
= 64Mbyte
사원번호 (8)
이름 (10)
생년월일 (8)
입사일 (8)
직급 (8)
연봉 (4)
부서코드 (8) 부서코드 (8)
부서명 (12)
부서사업장주소 (100)
부서장이름 (10)
40만 레코드 X 46 Byte
= 18,400,000 Byte
= 17.5Mbyte
100 레코드X 130Byte
= 12Kbyte
EMP 테이블 사원 테이블
부서 테이블
2014 자바카페 SQL 동영상 스터디 이정근
조인을 사용하면 성능이 떨어진다?
A : 정규화를 하면 저장공간 및 I/O
부하가 줄어듬
17
2014 자바카페 SQL 동영상 스터디 이정근
count(*) > 0
SELECT (*) AS CNT FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN’;
;
If(rs.getString("CNT") > 0){
…
}
Or
SELECT * FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN’;
If(rs.size() > 0){
…
}
18
2014 자바카페 SQL 동영상 스터디 이정근
count(*) > 0
SELECT COUNT(*) FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN ‘
AND ROWNUM <= 1;
If(rs.getString("CNT") > 0){
…
}
MS-SQL 인 경우 Top N 사용
19
2014 자바카페 SQL 동영상 스터디 이정근
count(*) > 0
EXISTS 서브쿼리
• 조건절을 만족하면 첫번째 레코드를 만나는 순간 True를 반환하고
서브쿼리를 종료
SELECT COUNT(*) FROM DUAL
WHERE EXISTS(
SELECT ‘x’ FROM BIG_EMP
WHERE MGR=‘7698’ AND JOB=‘SALESMAN'
);
If(rs.getString("CNT") > 0){
…
}
20
2014 자바카페 SQL 동영상 스터디 이정근
count(*) > 0
21
2014 자바카페 SQL 동영상 스터디 이정근
count(*) > 0
A : EXISTS 나 ROWNUM 을 사용하여
불필요한 작업을 제거
22
2014 자바카페 SQL 동영상 스터디 이정근
내림차순 인덱스 와 힌트절
조회하고자 하는 데이터의 특성상 가장 최근의 데이터부터 역순으로 인덱스를
조회하는 것이 유리할 경우가 있음
예)
• 신입사원의 입사정보조회
• 게시판의 최신 글 내용 조회
• 로그성 데이터의 정보조회
내림차순인덱스 생성하는 방법
CREATE INDEX I_EMP_EMPNO ON BIG_EMP (EMPNO DESC)
조회시 힌트를 사용하는 방법
SELECT /*+ INDEX_DESC (BIG_EMP I_EMP_EMPNO) */
EMPNO FROM BIG_EMP ROWNUM<10 ;
23
2014 자바카페 SQL 동영상 스터디 이정근
내림차순 인덱스 와 힌트절
A : 내림차순 인덱스와 힌트절을 사용
하여 검색 속도를 개선
24
2014 자바카페 SQL 동영상 스터디 이정근
LIKE, BETWEEN, <>, IN
SELECT PAYMENT FROM EMP
WHERE DEPARTMENT = 'SALES'
AND HIRE_DT > '201301' AND HIRE_DT < '201312';
EMP 의 ROW 갯수 40만
A : HIRE_DT > '201301' AND HIRE_DT < '201312'
B : HIRE_DT LIKE '2013%'
C : BETWEEN '201301' AND '201312'
D : HIRE_DT IN ('201301', '201302', '201303', '201304', '201305', '201306', '201307', '201308',
'201309', '201310', '201311', '201312')
소요시간 : D < B < C < A
A : 가급적이면 범위 검색 할 때 IN 을 사용하자
! 주의 . IN 을 사용시에 갯수를 적게 사용할것. 너무 많으면 시스템에 부하가 발생된다.
25
감사합니다.
여호와를 두려워하는 것이 지혜의 첫걸
음이요
거룩하신 분을 아는 것이 깨달음이다.
_잠언 9장 10절
Blog - http://blog.cjred.net
Homepage – http://cjred.net
26

More Related Content

What's hot

GA로 게임 로그 분석하기
GA로 게임 로그 분석하기GA로 게임 로그 분석하기
GA로 게임 로그 분석하기Alan Kang
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニックGenya Murakami
 
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】Hiro H.
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012Esun Kim
 
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012devCAT Studio, NEXON
 
MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용흥배 최
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱PgDay.Seoul
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들Chris Ohk
 
Djangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みDjangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みShinya Okano
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스noerror
 
[WWCS] 15분만에 끝내는 LinkedIn 활용법
[WWCS] 15분만에 끝내는 LinkedIn 활용법[WWCS] 15분만에 끝내는 LinkedIn 활용법
[WWCS] 15분만에 끝내는 LinkedIn 활용법SujinLee92
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
SSHの便利な使い方〜マイナーな小技編〜
SSHの便利な使い方〜マイナーな小技編〜SSHの便利な使い方〜マイナーな小技編〜
SSHの便利な使い方〜マイナーな小技編〜ktateish
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかYuki Miyatake
 
Triggers in SQL | Edureka
Triggers in SQL | EdurekaTriggers in SQL | Edureka
Triggers in SQL | EdurekaEdureka!
 
로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법Jeongsang Baek
 
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018devCAT Studio, NEXON
 
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스Dan Kang (강동한)
 
SOLID refactoring - racing car katas
SOLID refactoring - racing car katasSOLID refactoring - racing car katas
SOLID refactoring - racing car katasGeorg Berky
 

What's hot (20)

GA로 게임 로그 분석하기
GA로 게임 로그 분석하기GA로 게임 로그 분석하기
GA로 게임 로그 분석하기
 
Constexpr 中3女子テクニック
Constexpr 中3女子テクニックConstexpr 中3女子テクニック
Constexpr 中3女子テクニック
 
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
その文字列検索、std::string::findだけで大丈夫ですか?【Sapporo.cpp 第8回勉強会(2014.12.27)】
 
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
덤프 파일을 통한 사후 디버깅 실용 테크닉 NDC2012
 
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
 
MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용MongoDB 모바일 게임 개발에 사용
MongoDB 모바일 게임 개발에 사용
 
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
[pgday.Seoul 2022] POSTGRES 테스트코드로 기여하기 - 이동욱
 
Sql server T-sql basics ppt-3
Sql server T-sql basics  ppt-3Sql server T-sql basics  ppt-3
Sql server T-sql basics ppt-3
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 
Djangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組みDjangoのエントリポイントとアプリケーションの仕組み
Djangoのエントリポイントとアプリケーションの仕組み
 
NDC11_슈퍼클래스
NDC11_슈퍼클래스NDC11_슈퍼클래스
NDC11_슈퍼클래스
 
[WWCS] 15분만에 끝내는 LinkedIn 활용법
[WWCS] 15분만에 끝내는 LinkedIn 활용법[WWCS] 15분만에 끝내는 LinkedIn 활용법
[WWCS] 15분만에 끝내는 LinkedIn 활용법
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
SSHの便利な使い方〜マイナーな小技編〜
SSHの便利な使い方〜マイナーな小技編〜SSHの便利な使い方〜マイナーな小技編〜
SSHの便利な使い方〜マイナーな小技編〜
 
BoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうかBoostAsioで可読性を求めるのは間違っているだろうか
BoostAsioで可読性を求めるのは間違っているだろうか
 
Triggers in SQL | Edureka
Triggers in SQL | EdurekaTriggers in SQL | Edureka
Triggers in SQL | Edureka
 
로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법로그 기깔나게 잘 디자인하는 법
로그 기깔나게 잘 디자인하는 법
 
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018
전형규, 좋은 이름, 나쁜 이름, 이상한 이름, NDC2018
 
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
[Play.node] node.js 를 사용한 대규모 글로벌(+중국) 서비스
 
SOLID refactoring - racing car katas
SOLID refactoring - racing car katasSOLID refactoring - racing car katas
SOLID refactoring - racing car katas
 

Similar to 개발자들이 흔히 실수하는 SQL 7가지

ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기Kenu, GwangNam Heo
 
효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차희동 강
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL TuningPgDay.Seoul
 
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQLPgDay.Seoul
 
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle엑셈
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle엑셈
 
회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemyJc Kim
 
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2Seok-joon Yun
 
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracleSPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle엑셈
 
효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차희동 강
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124한 경만
 
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Senchamniktw
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crowJaeseung Ha
 
[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDWPgDay.Seoul
 
MySQL Performance Tuning (In Korean)
MySQL Performance Tuning (In Korean)MySQL Performance Tuning (In Korean)
MySQL Performance Tuning (In Korean)OracleMySQL
 

Similar to 개발자들이 흔히 실수하는 SQL 7가지 (20)

ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
ecdevday8 웹개발자의 약한고리 SQL 뛰어넘기
 
효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차효율적인Sql작성방법 2주차
효율적인Sql작성방법 2주차
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning
 
3.2 실행계획 sql 연산 (concatenation)
3.2 실행계획 sql 연산 (concatenation)3.2 실행계획 sql 연산 (concatenation)
3.2 실행계획 sql 연산 (concatenation)
 
NO PARALLEL DML
NO PARALLEL DMLNO PARALLEL DML
NO PARALLEL DML
 
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
[Pgday.Seoul 2021] 1. 예제로 살펴보는 포스트그레스큐엘의 독특한 SQL
 
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
배치 프로그램에서 튜닝대상 SQL 추출하기_Wh oracle
 
6.4 hints for access paths(index)
6.4 hints for access paths(index)6.4 hints for access paths(index)
6.4 hints for access paths(index)
 
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracleSQL Profile을 이용한 SQL Plan 변경_Wh oracle
SQL Profile을 이용한 SQL Plan 변경_Wh oracle
 
회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy회사에서 써보는 SQLAlchemy
회사에서 써보는 SQLAlchemy
 
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
[2015-06-19] Oracle 성능 최적화 및 품질 고도화 2
 
(오라클SQL기초강좌)상관 서브쿼리(Correlated Sub Query)
(오라클SQL기초강좌)상관 서브쿼리(Correlated Sub Query)(오라클SQL기초강좌)상관 서브쿼리(Correlated Sub Query)
(오라클SQL기초강좌)상관 서브쿼리(Correlated Sub Query)
 
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracleSPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
SPA(SQL Performance Analyze)를 이용한 통계 정보 수집_Wh oracle
 
효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차효율적인Sql작성방법 3주차
효율적인Sql작성방법 3주차
 
Database 튜닝 교육 110124
Database 튜닝 교육 110124Database 튜닝 교육 110124
Database 튜닝 교육 110124
 
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
한국 커뮤니티 데이 트랙2, 세션2 JavaScript 성능향상과 Sencha
 
20150212 c++11 features used in crow
20150212 c++11 features used in crow20150212 c++11 features used in crow
20150212 c++11 features used in crow
 
[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW[Pgday.Seoul 2019] Advanced FDW
[Pgday.Seoul 2019] Advanced FDW
 
3.9 실행계획 SQL 연산 (MERGE ANTI-JOIN)
3.9 실행계획 SQL 연산 (MERGE ANTI-JOIN)3.9 실행계획 SQL 연산 (MERGE ANTI-JOIN)
3.9 실행계획 SQL 연산 (MERGE ANTI-JOIN)
 
MySQL Performance Tuning (In Korean)
MySQL Performance Tuning (In Korean)MySQL Performance Tuning (In Korean)
MySQL Performance Tuning (In Korean)
 

More from JungGeun Lee

Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)JungGeun Lee
 
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)JungGeun Lee
 
20160409 microsoft 세미나 머신러닝관련 발표자료
20160409 microsoft 세미나 머신러닝관련 발표자료20160409 microsoft 세미나 머신러닝관련 발표자료
20160409 microsoft 세미나 머신러닝관련 발표자료JungGeun Lee
 
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝JungGeun Lee
 
자바기반 스케줄링 프로그래밍
자바기반 스케줄링 프로그래밍자바기반 스케줄링 프로그래밍
자바기반 스케줄링 프로그래밍JungGeun Lee
 
logback 세미나 발표자료
logback 세미나 발표자료logback 세미나 발표자료
logback 세미나 발표자료JungGeun Lee
 

More from JungGeun Lee (6)

Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)Concurrent Programming (Java thread 다루기)
Concurrent Programming (Java thread 다루기)
 
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)
20160409 microsoft 세미나 머신러닝관련 발표자료(축약본)
 
20160409 microsoft 세미나 머신러닝관련 발표자료
20160409 microsoft 세미나 머신러닝관련 발표자료20160409 microsoft 세미나 머신러닝관련 발표자료
20160409 microsoft 세미나 머신러닝관련 발표자료
 
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝
2016 kcd 세미나 발표자료. 구글포토로 바라본 인공지능과 머신러닝
 
자바기반 스케줄링 프로그래밍
자바기반 스케줄링 프로그래밍자바기반 스케줄링 프로그래밍
자바기반 스케줄링 프로그래밍
 
logback 세미나 발표자료
logback 세미나 발표자료logback 세미나 발표자료
logback 세미나 발표자료
 

개발자들이 흔히 실수하는 SQL 7가지

  • 1. 개발자가 흔히 실수하는 SQL 7가지 2014 자바카페 SQL 동영상 스터디 이정근 cjred77@gmail.com 1
  • 2. 2014 자바카페 SQL 동영상 스터디 이정근 1. SQL 파싱 순서 2. 인덱스 스캔, 풀스캔 3. 무조건 인덱스 많이 4. 조인을 사용하면 성능이 떨어진다? 5. count(*) > 0 6. 내림차순 인덱스 와 힌트절 7. LIKE BETWEEN, <>, IN 2
  • 3. 2014 자바카페 SQL 동영상 스터디 이정근 SQL 파싱 순서 SELECT * FROM BIG_EMP WHERE MGR=‘7698’ AND DEPTNO=’60’; 직원테이블(EMP) 의 총 사원수(레코드 개수) 28955명 메니져(MGR) 가 7698인 사원수 10,319명 부서(DEPTNO) 가 60 인 사원수 1263명 3 MGR 7698 etc DEPTNO 60 etc
  • 4. 2014 자바카페 SQL 동영상 스터디 이정근 SQL 파싱 순서 COST 기반 옵티마이져 인 경우 옵티마이져가 알아서 순서를 정함. (대부분의 경우 COST 기반 옵티마이져를 사용) RULE 기반 옵티마이져인 경우 이거나 RULE 을 사용하도록 힌트를 사용 하는 경우 1. 가장 나중에 생성한 인덱스가 있는 컬럼부터 파싱 2. 같은 경우 AND 는 WHERE 절에 가장 가까운 조건부터 뒤에서 부터 , OR 는 WHERE 절의 가장 오른쪽부터 파싱 DEPTNO=‘60' AND MGR=‘7698'; 앞 --> 뒤 DEPTNO=‘60' OR MGR=‘7698'; ; 앞 <-- 뒤 4
  • 5. 2014 자바카페 SQL 동영상 스터디 이정근 SQL 파싱 순서 5 MGR=‘7698' AND DEPTNO=‘60'; 앞 --> 뒤 DEPTNO=‘60' AND MGR=‘7698'; 앞 --> 뒤
  • 6. 2014 자바카페 SQL 동영상 스터디 이정근 SQL 파싱 순서 6 DEPTNO=‘60' OR MGR=‘7698'; 앞 <-- 뒤
  • 7. 2014 자바카페 SQL 동영상 스터디 이정근 SQL 파싱 순서 A : 일반적(COST 기반 옵티마이져) 으 로 WHERE 절 컬럼순서에 상관없음 7
  • 8. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 SELECT SAL FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN’; 8
  • 9. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 Single Block I/O (랜덤 액세스) • 인덱스를 사용하여 검색(인덱스 스캔)을 하게 되면 한번 의 I/O 요청에 한 블록씩 데이터를 읽는다. Multi Block I/O • 전체 데이블 검색(풀 스캔)은 데이터를 읽을 때 한번의 I/O 요청으로 여러 블록을 한꺼번에 읽는다. 9
  • 10. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 Single Block I/O 1. 인덱스 테이블에서 조건절 검색 MGR=‘7698' 2. ROWID 로 테이블 검색 (1만 ROW , 1만회 I/O) 3. 조건절 검색 ( JOB='SALESMAN') Multi Block I/O 1. 3만 / 150 = 2백회 IO 2. 조건절 검색 ( JOB=‘SALESMAN') 10 10만 I/O 2천 I/O
  • 11. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 풀 스캔을 유도하는 방법 • 인덱스가 걸린 컬럼을 가공 SELECT SAL FROM BIG_EMP WHERE MGR || ‘’ ='7698‘ AND JOB='SALESMAN'; • 힌트를 사용 SELECT /*+ FULL(EMP) */ SAL FROM BIG_EMP WHERE MGR='7698' AND JOB='SALESMAN'; 11
  • 12. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 12
  • 13. 2014 자바카페 SQL 동영상 스터디 이정근 인덱스 스캔, 풀 스캔 A : 인덱스컬럼의 조건이 대부분의 경 우에 포함되는 경우 풀 스캔이 더 성능 이 좋을 수 있음 13
  • 14. 2014 자바카페 SQL 동영상 스터디 이정근 무조건 인덱스 많이 SELECT SAL FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN’; • 인덱스를 만들거나 수정시 DB 성능 지연 발생 • 분포도가 좋지 않은 컬럼에 인덱스를 생성하더라도 성능에 영향이 적음. – 대부분의 LOCATION 컬럼값이 'SEOUL' 인 경우 오히려 Full Scan 이 유리 • INSERT, UPDATE, DELETE 시에 성능 저하 14
  • 15. 2014 자바카페 SQL 동영상 스터디 이정근 무조건 인덱스 많이 A : 인덱스를 꼭 필요한 경우에만 추가 해야 한다. 15
  • 16. 2014 자바카페 SQL 동영상 스터디 이정근 조인을 사용하면 성능이 떨어진다? A : 정규화를 하면 저장공간 및 I/O 부하가 줄어듬 16 사원번호 (8) 이름 (10) 생년월일 (8) 입사일 (8) 직급 (8) 연봉 (4) 부서명 (12) 부서사업장주소 (100) 부서장이름 (10) 40만 레코드 X 168 Byte = 67,200,000 Byte = 64Mbyte 사원번호 (8) 이름 (10) 생년월일 (8) 입사일 (8) 직급 (8) 연봉 (4) 부서코드 (8) 부서코드 (8) 부서명 (12) 부서사업장주소 (100) 부서장이름 (10) 40만 레코드 X 46 Byte = 18,400,000 Byte = 17.5Mbyte 100 레코드X 130Byte = 12Kbyte EMP 테이블 사원 테이블 부서 테이블
  • 17. 2014 자바카페 SQL 동영상 스터디 이정근 조인을 사용하면 성능이 떨어진다? A : 정규화를 하면 저장공간 및 I/O 부하가 줄어듬 17
  • 18. 2014 자바카페 SQL 동영상 스터디 이정근 count(*) > 0 SELECT (*) AS CNT FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN’; ; If(rs.getString("CNT") > 0){ … } Or SELECT * FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN’; If(rs.size() > 0){ … } 18
  • 19. 2014 자바카페 SQL 동영상 스터디 이정근 count(*) > 0 SELECT COUNT(*) FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN ‘ AND ROWNUM <= 1; If(rs.getString("CNT") > 0){ … } MS-SQL 인 경우 Top N 사용 19
  • 20. 2014 자바카페 SQL 동영상 스터디 이정근 count(*) > 0 EXISTS 서브쿼리 • 조건절을 만족하면 첫번째 레코드를 만나는 순간 True를 반환하고 서브쿼리를 종료 SELECT COUNT(*) FROM DUAL WHERE EXISTS( SELECT ‘x’ FROM BIG_EMP WHERE MGR=‘7698’ AND JOB=‘SALESMAN' ); If(rs.getString("CNT") > 0){ … } 20
  • 21. 2014 자바카페 SQL 동영상 스터디 이정근 count(*) > 0 21
  • 22. 2014 자바카페 SQL 동영상 스터디 이정근 count(*) > 0 A : EXISTS 나 ROWNUM 을 사용하여 불필요한 작업을 제거 22
  • 23. 2014 자바카페 SQL 동영상 스터디 이정근 내림차순 인덱스 와 힌트절 조회하고자 하는 데이터의 특성상 가장 최근의 데이터부터 역순으로 인덱스를 조회하는 것이 유리할 경우가 있음 예) • 신입사원의 입사정보조회 • 게시판의 최신 글 내용 조회 • 로그성 데이터의 정보조회 내림차순인덱스 생성하는 방법 CREATE INDEX I_EMP_EMPNO ON BIG_EMP (EMPNO DESC) 조회시 힌트를 사용하는 방법 SELECT /*+ INDEX_DESC (BIG_EMP I_EMP_EMPNO) */ EMPNO FROM BIG_EMP ROWNUM<10 ; 23
  • 24. 2014 자바카페 SQL 동영상 스터디 이정근 내림차순 인덱스 와 힌트절 A : 내림차순 인덱스와 힌트절을 사용 하여 검색 속도를 개선 24
  • 25. 2014 자바카페 SQL 동영상 스터디 이정근 LIKE, BETWEEN, <>, IN SELECT PAYMENT FROM EMP WHERE DEPARTMENT = 'SALES' AND HIRE_DT > '201301' AND HIRE_DT < '201312'; EMP 의 ROW 갯수 40만 A : HIRE_DT > '201301' AND HIRE_DT < '201312' B : HIRE_DT LIKE '2013%' C : BETWEEN '201301' AND '201312' D : HIRE_DT IN ('201301', '201302', '201303', '201304', '201305', '201306', '201307', '201308', '201309', '201310', '201311', '201312') 소요시간 : D < B < C < A A : 가급적이면 범위 검색 할 때 IN 을 사용하자 ! 주의 . IN 을 사용시에 갯수를 적게 사용할것. 너무 많으면 시스템에 부하가 발생된다. 25
  • 26. 감사합니다. 여호와를 두려워하는 것이 지혜의 첫걸 음이요 거룩하신 분을 아는 것이 깨달음이다. _잠언 9장 10절 Blog - http://blog.cjred.net Homepage – http://cjred.net 26

Editor's Notes

  1. 오늘은 시간관계상 5개만 소개하도록 하겠습니다. 각 타이틀을 다 읽어줄것
  2. 풀스캔을 강제하는 방법은 /*+ full(emp) */
  3. 테이블에 무조건 인덱스를 만드는 것은 비효율적이다. 인덱스를 만들거나 수정시 DB 성능 지연 발생 실제 구동하며 서비스하고 있는 DB에 아무리 작은 테이블이라도 인덱스를 생성하는 명령을 실행하면 0.001 초라도 DB서버는 버벅이게 된다. 이것은 no logging 등 별의별 옵션을 사용하도라도 기존 서비스에 영향도가 0% 라고 전혀 말 할 수 없다. 인덱스를 추가하는 것을 100% 반대하는 것은 아니지만 운영중에 인덱스를 추가하거나 수정하는 것은 가급적 피해야한다. 분포도가 좋지 않은 컬럼에 인덱스를 생성하더라도 성능에 영향이 적음. 분포도가 좋지 않다는것은 해당 컬럼의 값이 특정 값에 편중되어 있는 비율이 커서 차라리 Full Scan 을 통하여 조회를 하는 것이 유리하다는 것이다.(인덱스 손익분기점) 인덱스컬럼을 추가하던지(복합인덱스), 다른 컬럼을 사용하여 조회하도록 쿼리 튜닝하던지, Full Scan을 사용하는 방법을 고려해야 한다. INSERT, UPDATE, DELETE 시에 성능 저하 인덱스를 추가하게되면 당장 SELECT 시에 성능향상을 기대할 수 있겠지만, INSERT, UPDATE, DELETE 시에 오히려 성능이 저하된다. 일일히 해당 인덱스에서도 INSERT, UPDATE, DELETE 가 수행되기 때문이다. 저장공간의 낭비 과다한 인덱스 생성으로 실제 테이블공간과 비슷하거나 더 많은 저장소 공간을 차지하는 배보다 배꼽이 더 큰 경우도 발생되고 있다.
  4. 테이블에 무조건 인덱스를 만드는 것은 비효율적이다. 인덱스를 만들거나 수정시 DB 성능 지연 발생 실제 구동하며 서비스하고 있는 DB에 아무리 작은 테이블이라도 인덱스를 생성하는 명령을 실행하면 0.001 초라도 DB서버는 버벅이게 된다. 이것은 no logging 등 별의별 옵션을 사용하도라도 기존 서비스에 영향도가 0% 라고 전혀 말 할 수 없다. 인덱스를 추가하는 것을 100% 반대하는 것은 아니지만 운영중에 인덱스를 추가하거나 수정하는 것은 가급적 피해야한다. 분포도가 좋지 않은 컬럼에 인덱스를 생성하더라도 성능에 영향이 적음. 분포도가 좋지 않다는것은 해당 컬럼의 값이 특정 값에 편중되어 있는 비율이 커서 차라리 Full Scan 을 통하여 조회를 하는 것이 유리하다는 것이다.(인덱스 손익분기점) 인덱스컬럼을 추가하던지(복합인덱스), 다른 컬럼을 사용하여 조회하도록 쿼리 튜닝하던지, Full Scan을 사용하는 방법을 고려해야 한다. INSERT, UPDATE, DELETE 시에 성능 저하 인덱스를 추가하게되면 당장 SELECT 시에 성능향상을 기대할 수 있겠지만, INSERT, UPDATE, DELETE 시에 오히려 성능이 저하된다. 일일히 해당 인덱스에서도 INSERT, UPDATE, DELETE 가 수행되기 때문이다. 저장공간의 낭비 과다한 인덱스 생성으로 실제 테이블공간과 비슷하거나 더 많은 저장소 공간을 차지하는 배보다 배꼽이 더 큰 경우도 발생되고 있다.
  5. 
즉 저장공간에서는 3배가 줄어들게 되고 풀 스캔시 4배의 I/O 가 감소되게 된다. 실제 필드에서는 수천만 수억, 수십억의 레코드가 있는 테이블도 있으므로 성능의 차이는 더 커진다.
  6. 
즉 저장공간에서는 3배가 줄어들게 되고 풀 스캔시 4배의 I/O 가 감소되게 된다. 실제 필드에서는 수천만 수억, 수십억의 레코드가 있는 테이블도 있으므로 성능의 차이는 더 커진다.
  7. 자세한 설명은 생략한다..