개념,용어
page : 8kb, i/o 최소단위
Extent : 8Page(8kb*8=64kb), 할당의 최소단위
Heap : IAM(Index Alloction Map)를 통해서 관리, IAM 자체는 링크드 리스트
page split
nonclustered index : 지점(Point)에 유리
Heap 테이블의 경우 RID로 Rookup.
클러스터드 테이블의 경우 clustering kye로 seek.
구조상 클러스터인덱스를 한번더 타기 때문에 느릴것 같지만,
클러스터드 인덱스에서 리프가 아닌 노드들은 대부분 캐시에 저장되기 때문에
넌클로 검색해도 물리적 i/o는 그렇게 많지 않다..
clustered index : 리프노드에 실제 데이터를 가지고 있는 트리구조.
범위(Range)에 유리, 순차적(Sequential)한 정렬된 데이터 가져올 때 유리하다.
게다가 Read-Ahead 기능은 순차적 데이터를 매우 빠르게 읽을 수 있도록 도와준다.
고로.. Order by, Group by, Range Search에 사용하면 좋다.
참고.. 클러스터드 인덱스의 키값은 넌클러스터드 인덱스의 리프노드 포인으로 저장된다.
Covered Index
Index Hot Spot Problem
: 순차(Sequential)인 컬럼을 클러스터드 인덱스로 처리한 경우 대량 트랜잭션에서 인덱스의
마지막 페이지에 모든 I/0가 몰리게 되고, 페이지 잠금(Page Locking) 문제가 발생된다.
이런 경우 넌클러스터로 처리해서 I/O를 다른 페이지로 분산해야한다.
index intersection
인덱스 사용 유무는 액세스하는 데이터량에 의해 좌우된다.
액세스 데이터량이 많다면 인덱스 보다 fullscan이 낫다.
인덱스 사용시 액세스하는 논리적인 페이지의 양이 fullscan보다 많아지게 된다.
결합인덱스에서 컬럼의 분포도는 의미가 없다.
분포도는 동일한 값이 조건(=즉 이퀄 조건)인 경우에만 의미가 있다.
like나 between 연산자의 경우 분포도는 의미가 없다.
그럼 뭐가 중요한가? 점 조건과 선분 조건!!
해당 컬럼에 사용되는 연산자가 가장 중요하다.
(점 조건 : in, = 연산자 // 선분 조건 : 그외 모든 연산자)
결합 인덱스는 반드시 아래와 같은 특성을 가지게 된다.
● 점 조건+점 조건: 두 컬럼에 의해 처리 범위 감소
● 점 조건+선분 조건: 두 컬럼에 의해 처리 범위 감소
● 선분 조건+선분 조건: 앞의 선분 조건에 의해서만 처리 범위 감소
● 선분 조건+점 조건: 앞의 선분 조건에 의해서만 처리 범위 감소
분포도에 의한 결합 인덱스 선정이 아닌 연산자에 의한 결합 인덱스 선정의 중요성을 인식하라!!
인덱스 Access 방법 - http://serious-code.net/moin.cgi/SqlServerIndexTuning
선지식 : B-Tree, 더블 링크드 리스트
Unordered Clustered Index Scan/Table Scan : 인덱스 무시하고 IAM을 통한 스캔 검색
Unordered Covering Nonclustered Index Scan : 넌클을 IAM을 통한 스캔 검색
Ordered Clustered Index Scan : 클인덱스의 리프노드를 스캔 검색. 인덱스 조각화가 심한 경우 성능저하.
Ordered Covering Nonclustered Index Scan : 넌클 리프노드를 이용한 스캔 검색.인덱스 조각화의 영향이 있다.
NonClustered Index Seek + Ordered Partial Scan + Lookups : 반환 행수가 적은 쿼리인 경우 발생. 검색 범위가 넒은 경우 성능이 현저하게 떨어진다.
Unordered Nonclustered Index Scan + Lookups : 쿼리 결과를 필터링하는 조건절이 인덱스와 무관한 경우 발생.
검색 조건의 min값을 이용해 리프레벨의 노드를 찾은 다음, max값을 가지는 노드를 만날 때까지, 리프레벨 링크드 리스트를 따라가는 작업. 클러스터드 테이블이기때문에 룩업과정 필요하지 않다.
Clustered Index Seek + Ordered Partial Scan : 검색 조건이 인덱스 첫번째 키컬럼인 경우 발생.
Covering Nonclustered Index Seek + Ordered Partial Scan
인덱스 생성
. 생성 단계 : 기본 테이블 데이터 페이지에서 키 값 검색 -> 내부 정렬버퍼 용량 만큰 키값을 채운다-> 키값 정렬
-> 정렬 결과 디스크에 저장 -> 다시 기본 데이터 페이지에서 키 값 검색 -> 모두 찾을 때까지 반복..
. SORT_IN_TEMPDB 옵션 - 선지식:인덱스 생성 단계 - http://msdn.microsoft.com/ko-kr/library/ms188281.aspx
OFF인 경우 정렬 실행은 대상 파일 그룹에 저장. ON인 경우 정렬 버퍼 중간 결과 tempdb에 저장
tempdb가 대상 파일과 물리적으로 다른 공간에 있을 경우 성능향상을 꾀할 수 있다.
인덱스 익스텐트의 근접성을 향상시킬 수 있다.
정렬작업이 필요하지 않거나, 메모리에서 정렬을 수행할 수 있으면 SORT_IN_TEMPDB옵션은 무시된다.
클러스터드 인덱스인 경우 정렬결과가 데이터페이지와 같다=용량이 크다!!
. Include (2k5~)
Include된 컬럼은 리프레벨에만 들어가게 된다.
. 디스크 공간 요구 사항 - http://msdn.microsoft.com/ko-kr/library/ms191163.aspx
생성, 다시 작성, 삭제할 때 고려할 사항
인덱스 관리 포인트
i/o 병목 / 사용률 / 조각화 진단 -> 조각화 처리 (재구성, 재생성)
인덱스 조각화 확인
- Logical scan
fragmentation or Average fragmentation in percent or External
fragmentation
Out of order 페이지의 비율. 즉 논리적인 순서와 어긋나게 물리적으로 배치된 인덱스 페이지의 비율. Ordered scan 작업의 성능에 큰 영향을 미친다.
- Average page
density or Internal fragmentation
Logical scan framentation은 무조건 나쁜 것이지만, 페이지 밀도는 두 가지 측면을 가진다. 낮은 밀도를 가지는 인덱스에서 읽기 작업을 할 때에는 높은 밀도를 가지는 인덱스에서 작업하는 것보다 많은 페이지를 읽어들여야 하므로 불리하다. 하지만 쓰기 작업을 할 때에는 낮은 밀도를 가지는 쪽이 유리하다. 높은 밀도의 인덱스에 대해 쓰기 작업을 하는 경우, 새로운 행이 추가되면 페이지 스플릿, 즉 트리의 분할이 이루어질 가능성이 높기 때문이다. 즉 SELECT 작업을 주로 하는 테이블에서는 밀도가 높아야 하고, INSERT 작업을 자주 하는 OLTP 환경에서는 밀도가 낮아야 한다.
2K0
:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl18',this);" href="http://msdn.microsoft.com/en-us/library/aa258803(SQL.80).aspx">DBCC SHOWCONTIG 논리적 스캔조각화, 페이지밀도. 2가지 항목을 봐라2K5
:Track('ctl00_MTCS_main_ctl00|ctl00_MTCS_main_ctl02',this);" href="http://msdn.microsoft.com/ko-kr/library/ms188917.aspx">sys.dm_db_index_physical_stats(Transact-SQL) -- sql 재식작시 초기화된다.
인덱스 조각 모음
2K0
CREATE INDEX~ WITH DROP_EXISTING
- 페이지 압축
- 컬럼 변경
- FILLFACTOR, PAD_INDEX 변경
- 비클러스터형 인덱스를 클러스터형 인덱스로 변경
DBCC DBREINDEX
- 페이지 압축
- FILLFACTOR 변경
- 테이블의 모든 인덱스 일괄 적용 가능- 배타적 잠금이 걸린다 - 온라인 작업 불가!
DBCC INDEXDEFRAG
- 물리적인 리프 페이지의 순서를 논리적인 순서로 재정렬
- 기존에 지정된 FILLFACTOR 적용
2K5
ALTER INDEX PK_Employee_EmployeeID ON HumanResources.Employee REBUILD;
ALTER INDEX PK_ProductPhoto_ProductPhotoID ON Production.ProductPhoto REORGANIZE ;
Comparison of DBCC DBREINDEX to DBCC INDEXDEFRAG
Functionality
DBCC DBREINDEX
DBCC INDEXDEFRAG
Online/Offline
Offline
Online
Faster when logical fragmentation is:
High
Low
Parallel processing
Yes
No
Compacts pages
Yes
Yes
Can be stopped and restarted without losing work completed to that point
No
Yes
Able to untangle interleaved indexes
May reduce interleaving
No
Additional free space is required in the data file for defragmenting
Yes
No
Faster on larger indexes
Yes
No
Rebuilds statistics
Yes
No
Log space usage
High in full recovery mode (logs entire contents of the index), low in bulk logged or simple recovery mode (only logs allocation of space)
Varies based on the amount of work performed
May skip pages on busy systems
No
Yes
참고 지식
※ unique 라면 unique 조건을 꼭 적어주자!!!
※ 조각화 : i/o 성능과 관련
page split 발생 -> 논리적인 순서(Doubly Linked List)와 물리적 순서(Physical Order In Disk)가 일치하지 않게 된다.
-> disk head가 순차적으로 i/o 할 수 없다.
※ 조각화 범위 : 0 ~ 10 : 낮음, 10~20 : 중간, 20~30 : 높음 // 일반적으로 20%이하는 재구성, 그 이상은 재생성 한다.
※ 조각화율이 30%
이하라면 ALTER INDEX REORGANIZE, 30% 초과라면 ALTER INDEX
REBUILD 구문을 사용하는 것이 좋다고 한다.
※ 조각모음 : 인덱스 스캔쿼리의 성능향상이 가장 크다
※ 클러스터드 인덱스 생성할 때 테이블에 배타적 잠금이 걸린다. - 인덱스 생성시 해당 테이블에 대한 모든 작업이 블로킹.
※ 넌클러스터드 인덱스 생성할 때 테이블에 공유잠금이 걸린다. - 인덱스 생성시 읽기 작업만 가능.
※ 인덱스 재생성 시 주의 사항
- 로그가 꽤 많이 쌓이기 때문에 recovery mode=simple
- 인덱스 생성시 필요한 충분한 공간 확보! - 클러스터드 인덱스 생성시 테이블 크기의 약 120% 공간을 필요로 한다!
- SORT_IN_TEMPDB 옵션 사용시 I/O 경합을 감소 시킬 수 있다
- MAXDOP 쿼리 힌트. (2K0: 지원하지 않는다.) (2K5 : 지원한다)
- 2K5부터 인덱스 생성시 온라인 작업을 지원한다.
* 검색 시 i/o를 줄이기 위해 사용
* 조각화 관리 필요
DBCC (2k~)
- dbcc showcontig
- dbcc indexdefrag
- dbcc dbreindex
DMV (2k5~)
- sys.dm_db_index_usage_stats
사용 유무/사용률/유지관리비용
해당 인덱스가 처음 사용되는 순간 행 추가
서비스 중지, AUTO_CLOSE ON, DETACH 될 때 모든 행 제거
user_updates (=i,d,u의 stmt 개수, 처리된 rows cnt가 아님!) - sys.dm_db_missing_index_details
optimizer가 사용하려고 시도 했던 index - sys.dm_db_missing_index_group_stats
missing_index의 사용률
sys.dm_db_index_usage_stats 와 비슷 - sys.dm_db_missing_index_groups
DMF (2k5)
-
sys.dm_db_missing_index_columns
Table
- sys.index_columns (2k5~)
- sys.indexes (2k5~)
- sys.columns (2k5~)
- sys.objects (2k5~)
-
sysindexes (~2k)
-
syscolumns (~2k)
-
sysobjects (~2k)
SP
-
sp_MSindexspace
-
sp_helpindex
Function
-
SELECT INDEXPROPERTY
(object_id('titles'),
'UPKCL_titleidind',
'IndexDepth')
Create Index (2k~)
- create index ... with (options)
- create index ... wtih drop_existing (drop & create를 한번에 처리)
Alter Index (2k5~)
- alter index index_name on table_name reorganize (= dbcc indexdefrag)
- alter index index_name on table_name rebuild (= dbcc reindex)
Drop Index (2k~)
-
drop index index_name on table_name (2k5)
-
drop index table_name.index_name (2K)
DBCC
-
DBCC PGLINKAGE
-
DBCC IND
-
DBCC PAGE
-
DBCC TRACEON(TRACEON (3604))
'연구개발 > DBA' 카테고리의 다른 글
dbcc showcontif, dbcc indexdefag (0) | 2010.06.20 |
---|---|
인덱스,index 관련쿼리 (0) | 2010.06.20 |
응용 프로그램 성능 최적화를 위한 숨겨진 데이터 찾기 (0) | 2010.06.18 |
각 데이터베이스의 사용량 확인 (0) | 2010.06.18 |
PAGE 구조 파악 할 시 (0) | 2010.06.16 |