64.2. GIST 스포츠 토토#

64.2.1. 소개#

gist일반화 된 검색 트리를 나타냅니다. 균형 잡힌 트리 구조화 액세스 방법으로 임의의 인덱싱 체계를 구현하는 기본 템플릿 역할을합니다. B- 트리, R- 트리 및 기타 많은 인덱싱 체계를 구현할 수 있습니다.gist.

하나의 이점gist데이터베이스 전문가가 아닌 데이터 유형의 도메인 전문가가 적절한 액세스 방법을 사용하여 사용자 정의 데이터 유형을 개발할 수 있다는 것입니다..

여기의 정보 중 일부는 버클리의 GIST 인덱싱 프로젝트에있는 캘리포니아 대학교에서 파생되었습니다웹 사이트및 Marcel Kornacker의 논문,차세대 데이터베이스 시스템에 대한 액세스 방법. 그만큼gist구현postgresql주로 Teodor Sigaev와 Oleg Bartunov에 의해 유지되며 그들의 자세한 정보가 있습니다.웹 사이트.

64.2.2. 내장 운영자 클래스#

핵심PostgreSQL분포 포함gist운영자 클래스에 표시표 64.1. (일부 선택 모듈 중 일부는PostgreSQL : 문서 : 17 : 부록 F. 추가 제공된 모듈 및 스포츠 토토 사이트추가 제공gist운영자 클래스.)

표 64.1. 내장gist운영자 클래스

이름 스포츠 토토 가능한 연산자 주문 연산자
box_ops << (Box, Box) <-- (Box, Point)
& <(Box, Box)
&& (Box, Box)
& (Box, Box)
(Box, Box)
~ = (Box, Box)
@ (Box, Box)
<@ (box, box)
& <| (상자, 상자)
<< | (상자, 상자)
| (Box, Box)
| & (Box, Box)
Circle_ops << (원, 원) <- (원, 포인트)
& <(Circle, Circle)
& (Circle, Circle)
(원, 원)
<@ (Circle, Circle)
@ (Circle, Circle)
~ = (원, 원)
&& (원, 원)
| (원, 원)
<< | (원, 원)
& <| (원, 원)
| & (원, 원)
inet_ops << (inet, inet)
<< = (inet, inet)
(inet, inet)
= (inet, inet)
= (inet, inet)
< (inet, inet)
<(inet, inet)
<= (inet, inet)
(inet, inet)
= (inet, inet)
&& (inet, inet)
multirange_ops = (anymultirange, anymultirange)
&& (Anymultirange, Anymultirange)
&& (Anymultirange, AnyRange)
@ (Anymultirange, Anylement)
@ (anymultirange, anymultirange)
@ (Anymultirange, AnyRange)
<@ (anymultirange, anymultirange)
<@ (Anymultirange, AnyRange)
<< (Multirange, Anymultirange)
<< (Anymultirange, AnyRange)
(anymultirange, anymultirange)
(Anymultirange, AnyRange)
& <(anymultirange, anymultirange)
& <(Anymultirange, AnyRange)
& (anymultirange, anymultirange)
& (Anymultirange, AnyRange)
- |- (anymultirange, anymultirange)
- |- (anymultirange, AnyRange)
point_ops | (포인트, 포인트) <-- (포인트, 포인트)
<< (포인트, 포인트)
(포인트, 포인트)
<< | (포인트, 포인트)
~ = (포인트, 포인트)
<@ (포인트, 박스)
<@ (포인트, 다각형)
<@ (Point, Circle)
poly_ops << (다각형, 다각형) <-- (다각형, 포인트)
& <(다각형, 다각형)
& (다각형, 다각형)
(다각형, 다각형)
<@ (다각형, 다각형)
@ (다각형, 다각형)
~ = (다각형, 다각형)
&& (다각형, 다각형)
<< | (다각형, 다각형)
& <| (다각형, 다각형)
| & (다각형, 다각형)
| (다각형, 다각형)
Range_ops = (AnyRange, AnyRange)
&& (AnyRange, AnyRange)
&& (AnyRange, AnyMultirange)
@ (AnyRange, Anylement)
@ (AnyRange, AnyRange)
@ (AnyRange, AnyMultirange)
<@ (AnyRange, AnyRange)
<@ (AnyRange, AnyMultirange)
<< (AnyRange, AnyRange)
<< (AnyRange, AnyMultirange)
(AnyRange, AnyRange)
(AnyRange, AnyMultirange)
& <(AnyRange, AnyRange)
& <(AnyRange, AnyMultirange)
& (AnyRange, AnyRange)
& (AnyRange, AnyMultirange)
- |- (AnyRange, AnyRange)
- |- (AnyRange, AnyMultirange)
TSQUERY_OPS <@ (tsquery, tsquery)
@ (tsquery, tsquery)
tsvector_ops @@ (tsvector, tsquery)

역사적 이유로inet_ops운영자 클래스는 유형의 기본 클래스가 아닙니다inetandCIDR. 그것을 사용하려면의 클래스 이름을 언급하십시오.색인 생성, 예를 들어

GIST (my_inet_column inet_ops)를 사용하여 my_table에서 색인 생성;

64.2.3. 확장 성#

전통적으로 새로운 인덱스 액세스 방법을 구현하면 많은 어려운 작업이 의미했습니다. Lock Manager 및 Write-Ahead Log와 같은 데이터베이스의 내부 작업을 이해해야했습니다. 그만큼gist인터페이스에는 높은 수준의 추상화가있어 액세스 방법 구현자가 액세스하는 데이터 유형의 의미를 구현해야합니다. 그만큼gist레이어 자체는 동시성, 트리 구조를 로깅 및 검색합니다.

이 확장 성은 처리 할 수있는 데이터 측면에서 다른 표준 검색 트리의 확장 성과 혼동되어서는 안됩니다. 예를 들어,PostgreSQL확장 가능한 B- 트리 및 해시 인덱스를 지원합니다. 그것은 당신이 사용할 수 있다는 것을 의미합니다PostgreSQL원하는 데이터 유형을 통해 B- 트리 또는 해시를 구축하려면. 그러나 B- 트리는 범위 만 지원합니다.<, =, ), 해시 인덱스는 평등 쿼리 만 지원합니다.

따라서 색인 인 경우 A의 이미지 컬렉션이 표시됩니다.postgresqlb- 트리,와 같은 쿼리 만 발행 할 수 있습니다.imagex는 imagey와 동일합니다, imagex가 imagey보다 작습니다andimagex가 imagey보다 큽니다. 당신이 정의하는 방법에 따라Equals, 보다 작음and보다 큰이 맥락에서 이것은 유용 할 수 있습니다. 그러나 A를 사용함으로써gist기반 스포츠 토토, 도메인 별 질문을하는 방법을 만들 수 있습니다.말의 모든 이미지 찾기또는과다 노출 된 모든 이미지 찾기.

a를 얻는 데 필요한 모든 것gist액세스 방법 UP 및 실행은 트리의 키의 동작을 정의하는 여러 사용자 정의 메소드를 구현하는 것입니다. 물론 이러한 방법은 멋진 쿼리를 지원하기 위해 매우 화려해야하지만 모든 표준 쿼리 (B- 트리, R- 트리 등)의 경우 비교적 간단합니다. 요컨대gist확장 성과 일반성, 코드 재사용 및 깨끗한 인터페이스를 결합합니다.

스포츠 토토 연산자가 클래스하는 5 가지 방법이 있습니다gist선택 사항을 제공해야합니다. 인덱스의 정확성은의 적절한 구현으로 보장됩니다.동일, 일관성andUnion방법, 스포츠 토토의 효율 (크기 및 속도)은에 따라 다릅니다.페널티andpicksplit방법. 두 가지 선택 방법은입니다.압축andDecompress, 스포츠 토토가 색인이 스포츠 토토되는 데이터와 다른 유형의 내부 트리 데이터를 가질 수 있습니다. 잎은 색인화 된 데이터 유형이어야하며 다른 트리 노드는 C 구조물 일 수 있습니다 (그러나 여전히 따라야합니다PostgreSQL데이터 유형 규칙은 여기에 참조Varlena가변 크기의 데이터의 경우). 트리의 내부 데이터 유형이 SQL 레벨에 존재하는 경우스토리지옵션운영자 클래스 만들기명령을 사용할 수 있습니다. 선택적 8 번째 방법은입니다.거리, 운영자 클래스가 주문 된 스캔을 지원하려는 경우 (가장 가까운 이웃 검색). 선택적 아홉 번째 방법fet스포츠 토토운영자 클래스가 인덱스 전용 스캔을 지원하려는 경우압축메소드가 생략되었습니다. 선택적 10 번째 방법옵션운영자 클래스에 사용자 지정 매개 변수가있는 경우 필요합니다. 옵션 11 번째 방법SortsUpport건물 속도를 높이는 데 사용됩니다gistindex.

일관성

스포츠 토토 항목이 주어진P및 쿼리 값Q,이 함수는 스포츠 토토 항목이 |일관성쿼리와 함께; 즉, 술어가 될 수 있습니다indexed_column indexable_operator Q인덱스 항목으로 표시되는 행에 대해 진실해야합니까? 리프 인덱스 항목의 경우 이것은 인덱스 가능한 조건을 테스트하는 것과 동일하지만 내부 트리 노드의 경우 트리 노드로 표시된 인덱스의 하위 트리를 스캔 해야하는지 여부가 결정됩니다. 결과가true, a다시 확인플래그도 반환해야합니다. 이것은 술어가 확실히 사실인지, 아마도 사실인지를 나타냅니다. 만약에다시 확인=거짓그러면 스포츠 토토가 술어 조건을 정확하게 테스트 한 반면다시 확인=true행은 후보 일뿐입니다. 이 경우 시스템은 자동으로를 평가합니다.indexable_operator실제 행 값에 대해 실제로 일치하는지 확인하십시오. 이 대회는 허용gist무손실 및 손실 인덱스 구조를 모두 지원합니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_consistent (내부, data_type, smallint, oid, 내부)
Bool을 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_consistent);

자료
my_consistent (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    data_type *query = pg_getarg_data_type_p (1);
    StrategyNumber Strategy = (StrategyNumber) pg_getarg_uint16 (2);
    /* OID 하위 유형 = PG_GETARG_OID (3); */
    bool *recheck = (bool *) pg_getarg_pointer (4);
    data_type *key = datumgetDatatype (enther- key);
    부리 retval;

    /*
     * 전략, 키 및 쿼리의 함수로 반환 값을 결정하십시오.
     *
     * gist_leaf (Entry)를 사용하여 인덱스 트리에서 호출되는 위치를 알 수 있습니다.
     * 예를 들어 = 연산자를 지원할 때 편리합니다 (예 :
     * 비 잎 노드에서 비 빈 연합 ()을 확인하고 잎의 평등을 확인하십시오.
     * 노드).
     */

    *다시 확인 = 참;        / * 또는 확인이 정확한 경우 false */

    pg_return_bool (retval);

여기,index and의 요소입니다.쿼리인덱스에서 찾은 값. 그만큼StrategyNumber매개 변수가 적용되는 운영자 클래스의 운영자가 나타납니다.의 연산자 번호 중 하나와 일치합니다.운영자 클래스 만들기명령.

클래스에 포함 된 연산자에 따라 데이터 유형의 데이터 유형쿼리운영자마다 다를 수 있습니다. 연산자의 오른쪽에있는 유형이 있으므로 왼쪽에 나타나는 색인화 된 데이터 유형과 다를 수 있습니다. (위의 코드 골격은 하나의 유형 만 가능하다고 가정합니다. 그렇지 않은 경우쿼리인수 값은 연산자에 의존해야합니다.) SQL 선언은 권장됩니다.일관성함수 OPClass의 스포츠 토토 데이터 유형을 사용하여쿼리인수, 실제 유형이 연산자에 따라 다른 것일 수 있지만

Union

이 방법은 트리의 정보를 통합합니다. 항목 세트가 주어지면이 기능은 주어진 모든 항목을 나타내는 새 스포츠 토토 항목을 생성합니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_union (내부, 내부)
Storage_type를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드 가이 골격을 따를 수 있습니다 :

pg_function_info_v1 (my_union);

자료
my_union (pg_function_args)

    gistentRyvector *entryVec = (gistentRyvector *) pg_getarg_pointer (0);
    gistentry *ent = EntryVec- 벡터;
    data_type *out,
               *TMP,
               *오래된;
    int numranges,
                i = 0;

    numranges = actorvevec- n;
    tmp = DatumgetDatatype (ENT [0] .key);
    out = tmp;

    if (numranges == 1)

        out = data_type_deep_copy (tmp);

        pg_return_data_type_p (out);

    for (i = 1; i <numranges; i ++)

        old = out;
        tmp = DatumgetDatatype (ent [i] .key);
        out = my_union_implementation (out, tmp);

    pg_return_data_type_p (out);

당신이 볼 수 있듯이,이 골격에서 우리는 데이터 유형을 다루고 있습니다Union (X, Y, Z) = Union (Union (X, Y), Z). 이 경우에는 그렇지 않은 경우 데이터 유형을 지원하기가 쉽습니다.gist지원 방법.

결과의 결과Union함수는 인덱스 스토리지 유형의 값이어야합니다. 그만큼Union함수는 새로 포인터를 반환해야합니다palloc ()ed 메모리. 유형 변경이 없더라도 입력 값을 반환 할 수는 없습니다.

위와 같이,Union기능의 첫 번째내부인수는 실제로 A입니다.GistentRyvector포인터. 두 번째 인수는 정수 변수에 대한 포인터이며, 이는 무시할 수 있습니다. (예전에는Union함수 결과 값의 크기를 해당 변수에 저장하지만 더 이상 필요하지 않습니다.)

압축

스포츠 토토 페이지의 물리적 저장에 적합한 형식으로 데이터 항목을 변환합니다. 인 경우compress메소드가 생략되고, 데이터 항목은 수정없이 스포츠 토토에 저장됩니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_compress (내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_compress);

자료
my_compress (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    gistentry *retval;

    if (Entry- Leafkey)

        / * 입력- 키를 압축 버전으로 교체하십시오 */
        compressed_data_type *compressed_data = palloc (sizeof (compressed_data_type));

        / *채우기 *Entry- 키 ... */

        retval = palloc (sizeof (gistentry));
        gistentryinit (*retval, pointergetDatum (compressed_data),
                      Entry- Rel, Entry- Page, Entry- 오프셋, False);

    또 다른

        / * 일반적으로 우리는 잎이 아닌 항목으로 아무것도 할 필요가 없습니다 */
        retval = 진입;

    pg_return_pointer (retval);

당신은 적응해야합니다compressed_data_type물론 잎 노드를 압축하기 위해 변환하는 특정 유형으로..

Decompress

저장된 데이터 항목의 표현을 운영자 클래스의 다른 GIST 메소드에 의해 조작 할 수있는 형식으로 변환합니다. 인 경우Decompress메소드가 생략되면 다른 GIST 방법이 저장된 데이터 형식에서 직접 작동 할 수 있다고 가정합니다. (Decompress반드시의 반대 일 필요는 없습니다.압축메소드; 특히압축손실이 없으면 불가능합니다Decompress원래 데이터를 정확하게 재구성하려면Decompress반드시 동등한 것은 아닙니다Fet스포츠 토토, 다른 GIST 방법은 데이터의 전체 재구성이 필요하지 않을 수 있으므로.)

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_decompress (내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_decompress);

자료
my_decompress (pg_function_args)

    pg_return_pointer (pg_getarg_pointer (0));

위의 골격은 감압이 필요하지 않은 경우에 적합합니다. (물론, 방법을 완전히 생략하는 것은 훨씬 쉽고 그러한 경우에 권장됩니다.)

페널티

값을 나타내는 값을 반환합니다비용새 항목을 나무의 특정 분기에 삽입하는 것. 항목은 최소 경로에 삽입됩니다페널티나무에서. 값페널티는 무분별하지 않아야합니다. 음수 값이 반환되면 0으로 취급됩니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_penalty (내부, 내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;  - 경우에 따라 페널티 기능이 엄격 할 필요는 없습니다

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_penalty);

자료
my_penalty (pg_function_args)

    gistentry *origentry = (gistentry *) pg_getarg_pointer (0);
    gistentry *newentry = (gistentry *) pg_getarg_pointer (1);
    float *penalty = (float *) pg_getarg_pointer (2);
    data_type *orig = datumgetDatatype (Origentry- 키);
    data_type *new = DatumgetDatatype (newentry- 키);

    *penalty = my_penalty_implementation (Orig, New);
    pg_return_pointer (페널티);

역사적 이유로페널티함수는 a를 반환하지 않습니다.float결과; 대신 세 번째 인수로 표시된 위치에 값을 저장해야합니다. 반환 값 자체는 무시되지만 해당 주장의 주소를 전달하는 것은 기존입니다.

the페널티함수는 인덱스의 우수한 성능에 중요합니다. 트리에 새 항목을 추가 할 위치를 선택할 때 따라야 할 지점을 결정하기 위해 삽입 시간에 사용됩니다. 쿼리 시점에서 인덱스의 균형이 높아질수록 조회가 빨라집니다.

picksplit

인덱스 페이지 분할이 필요한 경우이 기능은 페이지의 항목이 이전 페이지에 유지되고 새 페이지로 이동할 것인지 결정합니다..

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_picksplit (내부, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_picksplit);

자료
my_picksplit (pg_function_args)

    gistentRyvector *entryVec = (gistentRyvector *) pg_getarg_pointer (0);
    gist_splitvec *v = (gist_splitvec *) pg_getarg_pointer (1);
    OffsetNumber maxoff = EntryVec- n -1;
    gistentry *ent = EntryVec- 벡터;
    INT I,
                nbytes;
    오프셋 너버 *왼쪽,
               *오른쪽;
    data_type *tmp_union;
    data_type *Unionl;
    data_type *Unionr;
    gistentry ** raw_entryvec;

    maxoff = EntryVec- n -1;
    nbytes = (maxoff + 1) * sizeof (offsetNumber);

    v- spl_left = (OffsetNumber *) palloc (nbytes);
    왼쪽 = v- spl_left;
    v- spl_nleft = 0;

    v- spl_right = (OffsetNumber *) palloc (nbytes);
    오른쪽 = v- spl_right;
    v- spl_nright = 0;

    Unionl = null;
    Unionr = null;

    /* 원시 입력 벡터를 초기화합니다. */
    raw_entryvec = (gistentry **) malloc (EntryVec- n *sizeof (void *));
    for (i = firstOffSetNumber; i <= maxOff; i = OffSetNumberNext (i))
        raw_entryvec [i] = & (EntryVec- 벡터 [i]);

    for (i = firstOffSetNumber; i <= maxOff; i = OffSetNumberNext (i))

        int real_index = raw_entryvec [i] - EntryVec- 벡터;

        TMP_UNION = DATUMGETDATATYPE (EntryVec- 벡터 [real_index] .key);
        assert (tmp_union! = null);

        /*
         * 인덱스 항목을 넣을 위치를 선택하고 Unionl 및 UnionR 업데이트
         * 따라서. v- spl_left 또는에 대한 항목을 추가하십시오
         * v- spl_right, 카운터에 관심이 있습니다.
         */

        if (my_choice_is_left (Unionl, Curl, Unionr, Curr))

            if (UnionL == null)
                Unionl = tmp_union;
            또 다른
                Unionl = my_union_implementation (Unionl, Tmp_union);

            *왼쪽 = real_index;
            ++ 왼쪽;
            ++ (v- spl_nleft);

        또 다른

            /*
             * 오른쪽에 동일합니다
             */

    v- spl_ldatum = DataTypeGetDatum (Unionl);
    v- spl_rdatum = DataTypeGetDatum (UnionR);
    pg_return_pointer (V);

picksplit함수의 결과는 전달 된 수정을 통해 전달됩니다V구조. 반환 값 자체는 무시되지만의 주소를 전달하는 것은 기존입니다.V.

좋아요페널티,picksplit함수는 스포츠 토토의 우수한 성능에 중요합니다. 적절한 디자인페널티picksplit구현은 성능이 우수한 구현의 과제입니다gist인덱스 거짓말.

동일

두 인덱스 항목이 동일하면, 그렇지 않으면 false 인 경우 true를 반환합니다. (an색인 입력는 원래 인덱스 열 유형이 아니라 인덱스 스토리지 유형의 값입니다.)

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_same (Storage_type, Storage_type, 내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_same);

자료
my_same (pg_function_args)

    prefix_range *v1 = pg_getarg_prefix_range_p (0);
    prefix_range *v2 = pg_getarg_prefix_range_p (1);
    bool *result = (bool *) pg_getarg_pointer (2);

    *결과 = my_eq (v1, v2);
    pg_return_pointer (결과);

역사적 이유로동일함수는 부울 결과를 반환하지 않습니다. 대신 깃발을 세 번째 인수로 표시된 위치에 저장해야합니다. 반환 값 자체는 무시되지만 해당 주장의 주소를 전달하는 것은 기존입니다.

거리

스포츠 토토 항목 주어진P및 쿼리 값Q,이 함수는 스포츠 토토 항목을 결정합니다거리쿼리 값에서. 운영자 클래스에 주문 연산자가 포함 된 경우이 기능을 제공해야합니다. 주문 연산자를 사용하는 쿼리는 가장 작은 인덱스 항목을 반환하여 구현됩니다.거리값 먼저 값이므로 결과는 운영자의 의미와 일치해야합니다. 리프 인덱스 항목의 경우 결과는 인덱스 항목까지의 거리를 나타냅니다. 내부 트리 노드의 경우 결과는 모든 어린이 입국이 가질 수있는 가장 작은 거리 여야합니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_distance (내부, data_type, smallint, oid, 내부)
float8을 반환합니다
'module_pathname'으로
언어 C 엄격한;

그리고 C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_distance);

자료
my_distance (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    data_type *query = pg_getarg_data_type_p (1);
    StrategyNumber Strategy = (StrategyNumber) pg_getarg_uint16 (2);
    /* OID 하위 유형 = PG_GETARG_OID (3); */
    / *bool *recheck = (bool *) pg_getarg_pointer (4); */
    data_type *key = datumgetDatatype (enther- key);
    이중 retval;

    /*
     * 전략, 키 및 쿼리의 함수로 반환 값을 결정하십시오.
     */

    pg_return_float8 (retval);

에 대한 인수거리함수는의 인수와 동일합니다.일관성기능.

결과가 실제 거리보다 크지 않는 한 거리를 결정할 때 약간의 근사치가 허용됩니다. 따라서, 예를 들어, 경계 박스까지의 거리는 일반적으로 기하학적 응용 분야에서 충분합니다. 내부 트리 노드의 경우 반환 된 거리는 하위 노드와의 거리보다 크지 않아야합니다. 반환 된 거리가 정확하지 않은 경우 함수가 설정되어야합니다*리키크true. (이것은 내부 트리 노드에 필요하지 않습니다. 그들에게는 계산은 항상 부정확 한 것으로 가정합니다.)이 경우 executor는 힙에서 튜플을 가져온 후 정확한 거리를 계산하고 필요한 경우 튜플을 다시 주문합니다..

거리 함수가 반환되는 경우*Recheck = true모든 리프 노드의 경우 원래 순서 연산자의 반환 유형이이어야합니다.float8또는float4, 그리고 거리 함수의 결과 값은 원래 순서 연산자의 결과 값과 비교할 수 있어야합니다. 실행자는 거리 기능 결과와 순서 운영자 결과를 모두 사용하여 정렬하기 때문입니다. 그렇지 않으면 거리 함수의 결과 값은 유한 할 수 있습니다float8값, 결과 값의 상대적 순서가 주문 연산자가 반환 한 순서와 일치하는 한 값. (무한대 및 마이너스 무한대는 내부적으로 널과 같은 케이스를 처리하는 데 사용되므로 권장되지 않습니다.거리함수는이 값을 반환합니다.)

Fet스포츠 토토

인덱스 전용 스캔을 위해 데이터 항목의 압축 인덱스 표현을 원래 데이터 유형으로 변환합니다. 반환 된 데이터는 원래 인덱스 값의 정확하고 거친 사본이어야합니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_fet스포츠 토토 (내부)
내부를 반환합니다
'module_pathname'으로
언어 C 엄격한;

​​인수는 A에 대한 포인터입니다gistentrystruct. 진입시, 그것의필드에는 압축 형태의 비 널 리프 데이텀이 포함되어 있습니다. 반환 값은 다른 것입니다gistentrystruct, 누구필드에는 원래의 원래의 비 압축 형태로 동일한 기준이 포함되어 있습니다. OPCLASS의 압축 기능이 잎 항목에 대해 아무것도하지 않으면Fet스포츠 토토메소드는 인수를 반환 할 수 있습니다. 또는 opclass에 압축 기능이 없으면fet스포츠 토토메소드도 생략 할 수 있습니다.

C 모듈의 일치하는 코드는이 골격을 따를 수 있습니다.

pg_function_info_v1 (my_fet스포츠 토토);

자료
my_fet스포츠 토토 (pg_function_args)

    gistentry *entry = (gistentry *) pg_getarg_pointer (0);
    input_data_type *in = DatumgetPointer (entry- 키);
    fet스포츠 토토ed_data_type *fet스포츠 토토ed_data;
    gistentry *retval;

    retval = palloc (sizeof (gistentry));
    fet스포츠 토토ed_data = palloc (sizeof (fet스포츠 토토ed_data_type));

    /*
     * 'fet스포츠 토토ed_data'를 원래 데이터 유형의 A Datum으로 변환하십시오.
     */

    / * fet스포츠 토토ed_data의 retval * 채우기. */
    gistentryinit (*retval, pointergetDatum (converted_datum),
                  Entry- Rel, Entry- Page, Entry- 오프셋, False);

    pg_return_pointer (retval);

잎 항목에 대한 압축 방법이 손실되면 운영자 클래스는 인덱스 전용 스캔을 지원할 수 없으며 A를 정의해서는 안됩니다.fet스포츠 토토함수.

옵션

운영자 클래스 동작을 제어하는 ​​사용자가 가시 가능한 매개 변수를 정의 할 수 있습니다.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_options (내부)
void를 반환합니다
'module_pathname'으로
언어 C 엄격한;

함수는 A로 포인터가 전달됩니다local_relopts구조물은 일련의 운영자 클래스 특정 옵션으로 채워야합니다. 옵션은를 사용하여 다른 지원 기능에서 액세스 할 수 있습니다.pg_has_opclass_options ()andpg_get_opclass_options ()매크로.

my_options ()의 예제 구현 () 다른 지원 함수에서 사용하는 매개 변수는 다음과 같습니다.

typedef enum myenumtype

    my_enum_on,
    my_enum_off,
    my_enum_auto
 myEnumtype;

typedef struct

    int32 vl_len_;    / * Varlena 헤더 (직접 터치하지 마십시오!) */
    int int_param;  / * 정수 매개 변수 */
    Double real_param; / * 실제 매개 변수 */
    MyEnumtype enum_param; / * 열거 매개 변수 */
    int str_param;  / * 문자열 매개 변수 */
 myOptionsStruct;

/ * 열거 값의 문자열 표현 */
static replopt_enum_elt_def myenumvalues ​​[] =

     "on", my_enum_on,
     "off", my_enum_off,
     "auto", my_enum_auto,
    (const char *) null / *목록 터미네이터 * /
;

static char *str_param_default = "default";

/*
 * 샘플 유효성 검사기 : 문자열이 8 바이트를 넘지 않는지 확인합니다.
 */
정적 무효
validate_my_string_relopt (const char *value)

    if (strlen (value) 8)
        Ereport (오류,
                (errcode (errcode_invalid_parameter_value),
                 errmsg ( "str_param은 최대 8 바이트")));

/*
 * 샘플 필러 : 문자를 소문자로 전환합니다.
 */
정적 크기
fill_my_string_relopt (const char *value, void *ptr)

    char *tmp = str_tolower (값, strlen (value), default_collation_oid);
    int len ​​= strlen (tmp);

    if (ptr)
        strcpy ((char *) ptr, tmp);

    pfree (TMP);
    반환 Len + 1;

pg_function_info_v1 (my_options);

자료
my_options (pg_function_args)

    local_relopts *repopts = (local_relopts *) pg_getarg_pointer (0);

    init_local_reloptions (repopts, sizeof (myoptionsStruct));
    add_local_int_reloption (repopts, "int_param", "Integer 매개 변수",
                            100, 0, 100000,
                            오프셋 (myoptionsStruct, int_param));
    add_local_real_reloption (repopts, "real_param", "Real 매개 변수",
                             1.0, 0.0, 1000000.0,
                             오프셋 (myoptionsStruct, real_param));
    add_local_enum_reloption (repopts, "enum_param", "enum 매개 변수",
                             myEnumvalues, my_enum_on,
                             "유효한 값은 다음과 같습니다.
                             오프셋 (myoptionsStruct, enum_param));
    add_local_string_reloption (repopts, "str_param", "문자열 매개 변수",
                               str_param_default,
                               & validate_my_string_relopt,
                               & fill_my_string_relopt,
                               오프셋 (myoptionsStruct, str_param));

    pg_return_void ();

pg_function_info_v1 (my_compress);

자료
my_compress (pg_function_args)

    int int_param = 100;
    Double real_param = 1.0;
    myEnumtype enum_param = my_enum_on;
    char *str_param = str_param_default;

    /*
     * 일반적으로 OpClass에 '옵션'메소드가 포함 된 경우 옵션은 항상입니다.
     * 기능을 지원하기 위해 통과했습니다.  그러나 '옵션'메소드를 추가하면
     * 기존 OPCLASS, 이전에 정의 된 인덱스에는 옵션이 없으므로
     * 점검이 필요합니다.
     */
    if (pg_has_opclass_options ())

        myoptionsStruct *옵션 = (myoptionsStruct *) pg_get_opclass_options ();

        int_param = 옵션- int_param;
        real_param = 옵션- real_param;
        enum_param = 옵션- enum_param;
        str_param = get_string_reloption (옵션, str_param);

    / * 지원 기능의 나머지 구현 */

키를 표현한 이후gist는 유연하며 사용자 지정 매개 변수에 따라 다를 수 있습니다. 예를 들어, 키 서명의 길이를 지정할 수 있습니다. 보다gtsvector_options ()예를 들어.

SortsUpport

지역성을 보존하는 방식으로 데이터를 정렬하기 위해 비교 기능을 반환합니다. 에 의해 사용됩니다.색인 생성Reindex명령. 생성 된 인덱스의 품질은 비교기 함수에 의해 결정된 정렬 순서가 입력의 위치를 ​​얼마나 잘 보존하는지에 따라 다릅니다.

theSortsUpport메소드는 선택 사항입니다. 제공되지 않으면색인 생성|페널티picksplit함수, 훨씬 느린 기능.

theSQL함수 선언은 다음과 같아야합니다.

함수 생성 또는 교체 my_sortsupport (내부)
void를 반환합니다
'module_pathname'으로
언어 C 엄격한;

인수는 A에 대한 포인터입니다SortsUpportstruct. 최소한 함수는 비교기 필드를 채워야합니다. 비교기는 세 가지 인수를 취합니다 : 비교할 두 기준,에 대한 포인터SortsUpport구조. 데이텀은 스포츠 토토에 저장된 형식의 두 가지 스포츠 토토 값입니다. 즉,에 의해 반환 된 형식으로압축메소드. 전체 API는에 정의됩니다.src/include/utils/sortsupport.h.

C 모듈의 일치하는 코드는이 골격을 따라갈 수 있습니다.

pg_function_info_v1 (my_sortsupport);

정적 int
my_fastcmp (Datum X, Datum Y, Sortsupport SSUP)

  / * 어떤 정렬 값 z */를 계산하여 x와 y 사이의 순서 설정

  int z1 = computesPatialCode (x);
  int z2 = computesPatialCode (y);

  Z1 == Z2를 반환합니까? 0 : Z1 Z2? 1 : -1;

자료
my_sortsupport (pg_function_args)

  SortsUpport ssup = (SortSupport) pg_getarg_pointer (0);

  ssup- 비교기 = my_fastcmp;
  pg_return_void ();

모든 GIST 지원 방법은 일반적으로 단기간 메모리 컨텍스트에서 호출됩니다. 즉,currentMemoryContext각 튜플이 처리되면 재설정됩니다. 그러므로 당신이 palloc의 모든 것을 pfree에 대해 걱정하는 것은 그리 중요하지 않습니다. 그러나 경우에 따라 지원 방법이 반복 된 호출에서 데이터를 캐시하는 데 유용합니다. 그렇게하려면 더 긴 수명 데이터를 할당fcinfo- flinfo- fn_mcxtfcinfo- flinfo- fn_extra. 이러한 데이터는 인덱스 작동 수명 (예 : 단일 GIST 인덱스 스캔, 인덱스 빌드 또는 인덱스 튜플 삽입)에서 살아남을 것입니다. a를 교체 할 때 이전 값을 pfree에주의하십시오.fn_extra값 또는 작동 기간 동안 누출이 축적됩니다.

64.2.4. 구현#

64.2.4.1. Gist Index 빌드 방법#

GIST 스포츠 토토를 구축하는 가장 간단한 방법은 모든 항목을 하나씩 삽입하는 것입니다. 스포츠 토토 튜플이 스포츠 토토에 흩어져 있고 스포츠 토토가 캐시에 맞지 않을 정도로 크면 많은 임의의 I/O가 필요하기 때문에 큰 스포츠 토토의 경우 느리게 경향이 있습니다..PostgreSQLGIST 지수의 초기 빌드를위한 두 가지 대안 방법을 지원합니다.정렬and버퍼링모드.

정렬 된 메소드는 인덱스에서 사용하는 각 opclass가 a를 제공하는 경우에만 사용할 수 있습니다.SortsUpport함수, 설명대로섹션 64.2.3. 그들이 그렇게한다면,이 방법은 일반적으로 최고이므로 기본적으로 사용됩니다.

버퍼링 된 방법은 튜플을 인덱스에 직접 삽입하지 않음으로써 작동합니다. 비계 지정된 데이터 세트에 필요한 임의의 I/O의 양을 크게 줄일 수 있습니다. 잘 정리 된 데이터 세트의 경우, 적은 수의 페이지 만 한 번에 새 튜플을 받고 해당 페이지가 인덱스 전체가 아닌 경우에도 캐시에 적합하기 때문에 이점이 작거나 존재하지 않습니다..

버퍼링 된 메소드는를 호출해야합니다.페널티추가 CPU 리소스를 소비하는 간단한 방법보다 더 자주 기능합니다. 또한 버퍼는 결과 인덱스의 크기까지 임시 디스크 공간이 필요합니다. 버퍼링은 또한 긍정적 인 방향과 부정적인 방향으로 결과 인덱스의 품질에 영향을 줄 수 있습니다. 그 영향은 입력 데이터의 분포 및 운영자 클래스 구현과 같은 다양한 요인에 달려 있습니다.

정렬이 불가능한 경우 기본적으로 GIST 인덱스는 인덱스 크기에 도달하면 버퍼링 방법으로 전환됩니다explud_ca스포츠 토토e_size. 버퍼링은 수동으로 강제 또는 방지 할 수 있습니다.버퍼링create index 명령에 대한 매개 변수. 기본 동작은 대부분의 경우에 좋지만 입력 데이터가 주문되면 버퍼링을 끄면 빌드 속도를 높일 수 있습니다.

64.2.5. 예#

thePostgreSQL소스 분포는를 사용하여 구현 된 인덱스 방법의 몇 가지 예를 포함합니다gist. 핵심 시스템은 현재 텍스트 검색 지원을 제공합니다 (indexing forTSVECTORandtsquery) 및 내장 기하학적 데이터 유형 중 일부에 대한 R- 트리 동등한 기능 (참조src/backend/access/gist/gistproc.c). 다음Contrib모듈도 포함gist운영자 클래스 :

btree_gist

여러 데이터 유형에 대한 B- 트리 동등한 기능

큐브

다차원 큐브에 대한 인덱싱

HSTORE

저장을위한 모듈 (키, 값) pairs

intarray

int4 값의 1 차원 배열에 대한 RD-Tree

ltree

트리와 같은 구조에 대한 인덱싱

PG_TRGM

Trigram 매칭을 사용한 텍스트 유사성

SEG

indexing for플로트 범위

수정 제출

문서에 올바른 것이 없다면 일치하지 않습니다. 특정 기능에 대한 귀하의 경험 또는 추가 설명이 필요합니다. 사용이 양식문서 문제를보고하려면