Upload
maik
View
36
Download
0
Embed Size (px)
DESCRIPTION
데이터 타입. char 형 1∼255 바이트 저장되는 데이터가 고정형인 경우 주로 사용 고정길이이기 때문에 데이터가 작게 입력되어도 지정된 만큼의 저장공간을 가짐 => 공간낭비 ex) name char(10) name = ‘noh’. n. o. h. 공백. Varchar 형 1∼2000 바이트 지정길이보다 작은 데이터를 입력하면 데이터의 길이 만큼만 입력됨 ex) name varchar(10) name = ‘noh’ 10 개 이상의 문자를 입력하면 에러. n. o. - PowerPoint PPT Presentation
Citation preview
데이터 타입• char 형
– 1∼255 바이트– 저장되는 데이터가 고정형인 경우 주로
사용– 고 정 길 이 이 기 때 문 에 데 이 터 가 작 게
입력되어도 지정된 만큼의 저장공간을 가짐 =>공간낭비
ex) name char(10) name = ‘noh’
n o h공백
• Varchar 형– 1∼2000 바이트– 지 정 길 이 보 다 작 은 데 이 터 를
입력하면 데이터의 길이 만큼만 입력됨ex) name varchar(10) name = ‘noh’
• 10 개 이상의 문자를 입력하면 에러
n o h
Char 형과 varchar 형의 비교1.char 형과 char 형
Char(100)
Char(3)
noh
noh . . . . . . . . . . .
1) 100 번의 비교2) 모자라는 개수만큼 공백을 채워서 비교하기때문에 비교 시간이 길어진다 .3) 두 비교값은 같다고 나옴
2.char 형과 varchar 형
Char(100)
varchar(100)
noh
noh
1) 4 번의 비교로 끝냄2) 문자의 값은 같으나 char 형이 공백으로 채워져서 varchar 형보다 길기때문에 Char(100) 이 크다고 출력됨
3. Varchar 형과 varchar 형
noh
noh
Varchar(100)
Varchar(100)
1) 3 번의 비교로 끝남
상수값과의 비교COL1 char(7)
a b cblank
COL1 varchar(7)
a b c
COL1 = ‘abc’ COL2 = ‘abc’COL1 = COL2
1) 위와 같은 결과가 발생할 수도 있기때문에 주의해야함2) 될 수 있으면 특별한 경우를 제외하고는 앞서 살펴보았 듯이 varchar 형을 쓰는것이 유리함3) Char 형은 개발자들의 합의하에 최소한만 사용되는것이 좋다 .
• Date 타입– 년 , 월 , 일 , 시 , 분 , 초까지 입력됨– 두 date 타입을 ‘ =‘ 비교했을때 원하지
않는 결과가 나올 수 있으므로 주의 Ex) date hiredate // 선언
insert into emp(emp_name,newdate) values(‘ 노성섭’ ,sysdate);
insert into emp(emp_name,newdate) values(‘ 홍길동’ ,’15-oct-01’);
Select *from emp where newdate=’15-oct-01’; //추출
홍길동 15-oct-01
출력
//입력
• 앞 문제를 해결하는 sql– Select *from emp where to_char(newdate,’y
ymmdd’)=‘011015’– 이런경우 만약 newdate 에 인덱스가 잡혀
있다면 newdate 가 가공이 되어버렸기 때문에 인덱스를 사용할 수 없게 된다 .
• 이와 같은 이유로 date 타입도 특별한 경우가 아니면 되도록 사용하지 말고 char 형이나 varchar 형으로 사용할 것
Null• 주의점
– 어떤값과 null 을 연산하면 null 이 되어서 값이 소멸될 염려가 있음
– Nvl() 함수를 사용하여 이것을 방지할 수는 있지만 nvl() 함수의 연산이 추가되므로 수행속도가 저하됨
– 테이블을 만들때 숫자타입은 ‘ 0’ 을 , 문자타입일때는 공백이나 기타값을 디폴트로 지정해 주는 것이 좋다 .
– 값이 꼭 들어가야 하는 컬럼은 not null 을 꼭 지정하는것이 좋다 .
– 테이블을 대표하는 컬럼– 유일한 값을 가진다 .– 다른 컬럼의 외래키로 사용될 자격을 가진다 .– 기본키로 지정되면 자동적으로 인덱스가 생성된다 .
•기본키
•기본키와 외래키의 관계
Emp_no Emp_name Dept_no Dept_no Dept_name
Primary keyDepartment.Dept_no 컬럼으로 선언된 foreign key
Primary key
1 5 911
관리부 개발부 경리부 인사부
001002003004
노성섭홍길동이순신강감찬
1 111 9
Employee department
Employee.dept_no 의 값은 department.dept_no 에 있는 값 이외의값은 가질 수 없다 -> 참조 무결성
인덱스와 부분범위처리• Order by 의 대체
index table result
1
2
3
98
99
100
.
.
.
.
.
.
100
98
2
99
3
1
1
2
3
Create index 인덱스 이름 on 테이블이름 ( 컬럼이름 asc)
default
기존 sql: select emp_no from employee where emp_no < 4 order by emp_no;
개선 sql: select emp_no from employee where emp_no < 4;
•인덱스를 이용한 부분범위처리
기존 sql : select *from employee order by emp_no;개선 sql : select *from employee fetch first 1 row only;
index table result
100
99
98
3
2
1
.
.
.
.
.
.
100
98
2
99
3
1
100
Create index 인덱스 이름 on 테이블이름 ( 컬럼이름 desc)
문제 : 가장 최근데이터 한건 가져오기프로그램으로 해결
결합인덱스와 인덱스 merge •인덱스 merge
Select *from employee where col1=‘abc’ and col2=123;
col1 rowid
Index(col1)
col2 rowid
Index(col2)
AAA 10AAB 15ABC 26ABC 32ABC 53 ABC 55ABC 67BCA 27BCA 56 . .
. .100 29123 5
123 7123 9123 32123 35123 46123 67
. .
5
1
31
2
4
67
•결합인덱스Select *from employee where col1=‘abc’ and col2=123;
col1 col2 rowid
Index(col1 + col2)
AAA 55 10AAB 67 15ABC 70 55ABC 89 26ABC 123 32ABC 123 67ABC 172 53BCA 100 12BCA 100 27 . . . . .
12
3
결합인덱스 사용시 주의점1) 인덱스의 첫 컬럼이 사용되지 않으면 결합인덱스가 사용되지 않기 때문에 첫 컬럼을 잘 선택하는것이 중요2) 결합인덱스의 순서를 잘 선택해야 수 행속도의 향상을 꾀할 수 있다 . 순서는 분포도가 낮은 ( 좋은 ) 컬럼을 선택해야 한다 .3) 분포도가 큰 컬럼을 사용했을 때는 읽 는 양이 늘어나기 때문에 수행속도가 저하되는 경우가 있기 때문에 주의해 야 한다 .
Create index 인덱스 이름 on 테이블이름 ( 컬럼이름 1, 컬럼이름 2)
조인•조인순서에 대한 액세스 효율
1000rows
100rows
2rows 2rows
100rows
1000rows
최대 1102 회 , 최소 1000 회 최대 4 회 , 최소 2 회
조인을 할 때는 조인의 양이 적은 테이블이 먼저 액세스 되어야한다 .
•연결고리의 상태Sql 문에서 ‘ d.emp_no = e.emp_no’ 와 같은 것을 연결고리라한다 .
•연결고리 정상1) 연결고리 양쪽 모두에 인덱스가 있는경우를 말한다 .2) 액세스에는 문제가 없으므로 check 조건을 이용하여 처리범위를 줄여주는 것이 중요하다 .Ex) select *from employee e, department d where e.dept_no = d.dept_no and e.emp_no = 10 and d.dept_name = ‘abc%’•d.dept_name = ‘abc%’ 가 먼저 처리되는 경우
d.dept_name = ‘abc%’200row 추출
e.dept_no=d.dept_no50 row 추출
e.emp_no=102row 추출
총 252 row 액세스•‘e.emp_no = 10’ 이 먼저 처리되는 경우
e.emp_no=1010row 추출
e.dept_no=d.dept_no5 row 추출 2row 추출
d.dept_name = ‘abc%’
총 17row 추출연결고리 정상일때는 조건을 이용하여 범위를 줄여주는 것이 중요하다
•한쪽연결고리 이상 연결고리 한쪽에 인덱스가 없는 경우
•인덱스가 있는쪽이 먼저 액세스되는 경우
•인덱스가 없는쪽이 먼저 액세스되는 경우
인덱스있음 인덱스없음
tab1 tab2
1)Tab2 가 인덱스가 없기 때문에 전체 테이블 스켄을 하면서 조 건에 만족하는 행 추출 .2)Tab1 의 행의 개수만큼 전체 테 이블 스켄을 반복함 .
인덱스있음인덱스없음
1)tab1 이 인덱스가 있기 때문에 tab2 를 읽는 즉시 tab1 의 값을 찾아 갈 수 있다 .2)tab2 를 한번만 전체 스켄하면 된다 .
tab2 tab1
한쪽에 인덱스가 없는 경우에 인덱스가 없는 테이블이 먼저 읽히도록 해야한다
• 자신이 원하는 테이블이 먼저 액세스 되도록 하는 방법Ex) select *from employee e, department d
where e.dept_no = d.dept_no and e.emp_no = 10 and d.dept_name = ‘abc%’ 체크조건인 emp_no 와 dept_name 이 모두 인덱스가 잡혀있다고 가정한다 .
옵티마이져는 인덱스가 있는것을 우선적으로 읽기 때문에 두 인덱스중에 하나를 못쓰게 만들어 주면 된다 . 인덱스를 못쓰게 하는 방법은 인덱스가 잡혀있는 컬럼을 가공해 버리면 인덱스를 쓸 수 없게 된다 .
위의 sql 문에서 employee 테이블이 먼저 읽히게 하려면 department 테이블의 인덱스를 없애야 하므로
Select *from employee e, department d where e.dept_no = d.dept_no And e.emp_no = 10 and RTRIM(d.dept_name) = ‘abc%’
반대로 department 테이블을 먼저 읽히게 하려면 employee 테이블의 인덱스를 없애야 하므로
Select *from employee e, department d where e.dept_no = d.dept_no And NVL(e.emp_no,0) = 10 and d.dept_name = ‘abc%’ 와 같이 해주면 된다 .