Versions available for this page: CUBRID 9.0.0 |
필터링된 인덱스(filtered index)는 한 테이블에 대해 잘 정의된 부분 집합을 정렬하거나 찾거나 연산해야 할 때 사용되며, 전체 인덱스에서 조건에 부합하는 일부 인덱스만 사용되므로 부분 인덱스(partial index)라고도 한다. 필터링된 인덱스를 적용하여 질의를 처리하려면 USING INDEX 절에 해당 필터링된 인덱스를 반드시 명시해야 한다.
SELECT * FROM blogtopic WHERE postDate>'2010-01-01' USING INDEX my_filter_index;
CREATE /* hints */ INDEX index_name
ON table_name (col1, col2, ...) WHERE <filter_predicate>;
ALTER /* hints */ INDEX index_name
[ ON table_name (col1, col2, ...) [ WHERE <filter_predicate> ] ]
REBUILD;
<filter_predicate> ::= <filter_predicate> AND <expression> | <expression>
다음은 버그/이슈를 유지하는 버그 트래킹 시스템의 예이다. 일정 기간의 개발 활동 이후 bugs 테이블에는 버그들이 기록되어 있는데, 이들 대부분은 오래 전에 종료된 상태이다. 버그 트래킹 시스템은 여전히 열린(open) 상태의 새로운 버그를 찾기 위해 해당 테이블에 질의를 한다. 이 경우 버그 테이블의 인덱스는 닫힌(closed) 버그의 레코드들에 대해 알 필요가 없다. 이런 경우 필터링된 인덱스는 열린 버그만 인덱싱하는 것을 허용한다.
CREATE TABLE bugs
(
bugID BIGINT NOT NULL,
CreationDate TIMESTAMP,
Author VARCHAR(255),
Subject VARCHAR(255),
Description VARCHAR(255),
CurrentStatus INTEGER,
Closed SMALLINT
);
열린 상태의 버그만을 위한 인덱스는 다음 문장으로 생성될 수 있다.
CREATE INDEX idx_open_bugs ON bugs(bugID) WHERE Closed = 0;
열린 상태의 버그에만 관심있는 질의 처리를 위해 해당 인덱스를 USING INDEX 절에 명시하면, 필터링된 인덱스를 통하여 더 적은 인덱스 페이지를 접근하여 질의 결과를 생성할 수 있게 된다.
SELECT * FROM bugs
WHERE Author = 'madden' AND Subject LIKE '%fopen%' AND Closed = 0;
USING INDEX idx_open_bugs;
SELECT * FROM bugs
WHERE CreationDate > CURRENT_DATE - 10 AND Closed = 0;
USING INDEX idx_open_bugs;
필터링된 인덱스 생성 조건과 질의 조건이 부합되지 않음에도 불구하고 USING INDEX로 인덱스를 명시하여 질의를 수행하면 잘못된 질의 결과를 출력할 수 있음에 주의한다.
필터링된 인덱스는 일반 인덱스만 허용된다. 예를 들어, 필터링된 유일한(unique) 인덱스는 허용되지 않는다. 다음은 필터 조건으로 허용하지 않는 경우이다.
CREATE INDEX idx ON bugs(creationdate) WHERE creationdate > SYS_DATETIME;
ERROR: before ' ; '
'sys_datetime ' is not allowed in a filter expression for index.
CREATE INDEX idx ON bugs(bugID) WHERE bugID > RAND();
ERROR: before ' ; '
'rand ' is not allowed in a filter expression for index.
CREATE INDEX IDX ON bugs(bugID) WHERE bugID > 10 OR bugID = 3;
In line 1, column 62,
ERROR: before ' ; '
' or ' is not allowed in a filter expression for index.
CREATE TABLE t (a INT, b INT);
Current transaction has been committed.
-- IS NULL cannot be used with expressions
CREATE INDEX idx ON t (a) WHERE (not a) IS NULL;
ERROR: before ' ; '
Invalid filter expression (( not t.a<>0) is null ) for index.
CREATE INDEX idx ON t (a) WHERE (a+1) IS NULL;
ERROR: before ' ; '
Invalid filter expression ((t.a+1) is null ) for index.
-- At least one attribute must not be used with IS NULL
CREATE INDEX idx ON t(a,b) WHERE a IS NULL ;
ERROR: before ' ; '
Invalid filter expression (t.a is null ) for index.
CREATE INDEX idx ON t(a,b) WHERE a IS NULL and b IS NULL;
ERROR: before ' ; '
Invalid filter expression (t.a is null and t.b is null ) for index.
CREATE INDEX idx ON t(a,b) WHERE a IS NULL and b IS NOT NULL;
Current transaction has been committed.
CREATE TABLE t(VeryLongColumnNameOfTypeInteger INT);
1 command(s) successfully processed.
CREATE INDEX idx ON t(VeryLongColumnNameOfTypeInteger) WHERE VeryLongColumnNameOfTypeInteger > 3 AND VeryLongColumnNameOfTypeInteger < 10 AND sqrt(VeryLongColumnNameOfTypeInteger) < 3 AND SQRT(VeryLongColumnNameOfTypeInteger) < 10;
ERROR: before ' ; '
The maximum length of filter predicate string must be 128.