database.sarang.net
UserID
Passwd
Database
DBMS
MySQL
ㆍPostgreSQL
Firebird
Oracle
Informix
Sybase
MS-SQL
DB2
Cache
CUBRID
LDAP
ALTIBASE
Tibero
DB 문서들
스터디
Community
공지사항
자유게시판
구인|구직
DSN 갤러리
도움주신분들
Admin
운영게시판
최근게시물
PostgreSQL Tutorials 3831 게시물 읽기
 News | Q&A | Columns | Tutorials | Devel | Files | Links
No. 3831
부분 인덱스 사용법
작성자
정재익(advance)
작성일
2002-01-01 11:27
조회수
5,198

부분 인덱스라는 것은 테이블의 일부분만을 대상으로 생성된 인덱스를 말한다. 이 '일부분' 이라는 것은 조건문 (부분 인덱스의 서술부(predicate) 라고 한다)에 의해서 정의된다. 인덱스에는 이 서술부를 만족하는 테이블의 row 들만 포함된다.

부분 인덱스에 대한 주된 동기는 일반 값들에 대한 인덱싱을 피하자는 것이었다. 일반 값들을 모두 검색하는 Query 는 (테이블의 단지 몇퍼센트 만의 갯수를 세는 질의), 어찌 되었던 인덱스를 사용하지 않기 때문에, 그들 row 들을 인덱스에 유지시켜줄 방도가 전혀 없다. 이것은 인덱스의 사이즈를 줄일수 있고, 인덱스를 사용하는 질의의 속도를 향상시킬수 있다. 이것은 인덱스가 모든 update 동작 중에 필요하지는 않기 때문에 많은 테이블들의 update 도 상당항 속도 향상을 가져 올수 있다.

 

다음 예제 1은 이러한 생각을 응용시킬수 있는 방법을 보여 준다.

 

[예제 1]

 

웹서버 access log 를 데이터베이스에 저장한다고 가정하자. 그러면 테이블 구조는 다음과 같이 될 것이다.

CREATE TABLE access_log (
    url varchar,
    client_ip inet,
    ...
);

우리의 예제에 적당한 인덱스를 생성하고자 한다면 다음과 같이 만들면 될 것이다.

CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
    WHERE NOT (client_ip > inet '192.168.100.0' AND client_ip < inet '192.168.100.255');

이 인덱스를 이용하는 전형적인 질의는 다음과 같은 것이다 : 

SELECT * FROM access_log 
             WHERE url = '/index.html' AND client_ip = inet '212.78.10.32';

다음 질의는 이 인덱스를 사용할 수 없다 :

SELECT * FROM access_log 
            WHERE client_ip = inet '192.168.100.23';

위의 예제는 이런 종류의 부분 인덱스에서는 common value 가 이미 정의되어 있다는 것을 명심하기 바란다. 만약 이런 값들의 분포가 맘대로이고 (응용프로그램의 성격상) 그리고 정적이라면 (오랜시간을 두고 변치 않는), 이것은 어렵지 않다. 그러나 만약 common vlaue 가 단지 우연히 같이 발생하는 일치하는 자료라면 많은 유지보수작업이 필요하다.

 

또 다른 가능성은 인덱스로 부터 특정 값들을 제외시키는 것이며, 전형적인 질의들은 부하가 그렇게 문제되지 않는다. 이것은 예제 2 에서 볼수 있다. 이것도 위에서 언급한것과 같은 장점을 가진다. 그러나 이것은 "관심없는" 값들은 인덱스에서 전혀 접근하지 않도록 막아 버린다. 명확하기 이런 경우에 부분인덱스를 사용하는 것은 많은 주의와 실험이 필요하다.

 

[예제 2]

만약 여러분들이 계산을 한 주문과 계산을 하지 않은 주문이 포함된 테이블이 있다면, 그리고 계산을 하지 않은 주문이 총 테이블 중 일부 적은 부분을 차지하며, 그리고 대부분 access 하는 row 들이 또한 이 주문을 하지 않은 row 들이라면, 여러분들은 이 계산을 하지 않은 row 들에 대해서만 부분인덱스를 만들어 줌으로서 퍼포먼스를 향상 시킬수 있다. 이러한 경우 인덱스를 생성하는 명령어는 다음과 같다:

CREATE INDEX orders_unbilled_index ON orders (order_nr)
    WHERE billed is not true;

이 인덱스를 사용하는 가능한 질의는 다음과 같다.

 

SELECT * FROM orders

WHERE billed is not true AND order_nr < 10000;

[/pre]

그러나 order_nr 등이 전혀 관계 않는 질의에서도 인덱스가 이용될 수 있다. 예를 들면,

SELECT * FROM orders 
          WHERE billed is not true AND amount > 5000.00;

이것은 시스템이 전체 인덱스를 다 스캐닝하기 때문에 amount column 에 대해서 부분 인덱스를 생성한 것만큼 효율적이지 못하다. 만약 아직도 상대적으로 계산하지 않은 주문이 적다면, 계산하지 않은 주문에 대한 부분인덱스가 더 좋은 효율을 얻을수 있을 것이다.

 

다음 질의는 이 인덱스를 전혀 사용할수 없다는 것에 주의하기 바란다:

SELECT * FROM orders WHERE order_nr = 3501;

order 3501 이 계산한 주문이든지 아니면 계산하지 않은 주문이던지 간에 부분인덱스를 사용할 수 없다.

 

계속 작성중입니다

[Top]
No.
제목
작성자
작성일
조회
3846PL/pgSQL - SQL procedural language (3)
정재익
2002-01-07
13417
3845PL/pgSQL - SQL procedural language (2)
정재익
2002-01-07
8441
3844PL/pgSQL - SQL procedural language (1)
정재익
2002-01-07
8110
3831부분 인덱스 사용법
정재익
2002-01-01
5198
3822Quick HOWTO - connecting StarOffice Win or Lin to PostGreSQL using ODBC
정재익
2001-12-30
4469
3820Freeware PostgreSQL/iX for HP e3000 MPE
정재익
2001-12-30
3918
3817PostgreSQL FAQ - Sun Solaris specific
정재익
2001-12-29
3579
Valid XHTML 1.0!
All about the DATABASE... Copyleft 1999-2020 DSN, All rights reserved.
작업시간: 0.040초, 이곳 서비스는
	PostgreSQL v13.0으로 자료를 관리합니다