Postgresql 9.2.24 문서 | ||||
---|---|---|---|---|
토토 사이트 추천 : 문서 : 9.2 : 토토 사이트 추천 | 사설 토토 사이트 : 문서 : 9.2 : 사설 토토 사이트 Indexes | 53 장. GIST 토토 베이 | 젠 토토 : 문서 : 9.2 : 구현 |
전통적으로, 새로운 토토 베이 액세스 방법을 구현하면 a 많은 어려운 일. 내부를 이해해야했습니다 Lock Manager 및와 같은 데이터베이스의 작업 쓰기 로그. 그만큼gist인터페이스는 높은 수준의 추상화가있어 액세스가 필요합니다. 데이터의 의미를 구현하기위한 메소드 구현 자 액세스중인 유형. 그만큼gist레이어 자체는 동시성, 로깅 및 검색을 처리합니다. 나무 구조.
이 확장 성은 혼동되어서는 안됩니다 다른 표준 검색 트리의 확장 성 측면에서 그들이 처리 할 수있는 데이터. 예를 들어,토토 베이확장 가능한 B- 트리를 지원합니다 해시 토토 베이. 그것은 당신이 사용할 수 있다는 것을 의미합니다토토 베이B- 트리 또는 해시를 만들려면 원하는 데이터 유형. 그러나 B- 트리는 범위 만 지원합니다 (<, =, ), 해시 색인 만 지원합니다 평등 쿼리.
index (index, a의 이미지 컬렉션).토토 베이b- 트리, 만 발행 할 수 있습니다 와 같은 쿼리"는 imagex와 같습니다 imagey ", "는 ImageX보다 작습니다 imagey "and"는 ImageX보다 큽니다 imagey ". 당신이 정의하는 방법에 따라"Equals", ""보다 작습니다.및""보다 큰 "이 맥락에서, 이것은 유용 할 수 있습니다. 그러나 A를 사용함으로써gist기반 색인, 방법을 만들 수 있습니다 도메인 별 질문을하십시오. 아마도"찾기 말의 모든 이미지 "또는"모두 찾으십시오 과다 노출 된 이미지 ".
A를 얻는 데 필요한 모든gist액세스 메소드 UP 및 실행은 여러 사용자 정의를 구현하는 것입니다. 트리의 키의 동작을 정의하는 방법. 물론 이 방법은 멋진 쿼리를 지원하기 위해서는 매우 화려해야합니다. 그러나 모든 표준 쿼리 (B- 트리, R- 트리 등)에 대해 비교적 간단합니다. 요컨대gist와 함께 확장 성을 결합합니다 일반성, 코드 재사용 및 깨끗한 인터페이스.
토토 베이 연산자가에 대한 7 가지 방법이 있습니다gist제공해야합니다
8 번째 선택 사항입니다. 색인의 정확성은
의 적절한 구현동일
,
일관성
andUnion
효율성 (크기 및
토토 베이의 속도)는에 따라 다릅니다.페널티
andpicksplit
방법. 나머지 두 기본
방법은입니다.압축
및Decompress
, 토토 베이를 허용합니다
데이터와 다른 유형의 내부 트리 데이터가 있습니다.
토토 베이. 잎은 인덱싱 된 데이터 유형이어야하며
다른 트리 노드는 모든 C 구조물 일 수 있습니다 (그러나 여전히
따르다토토 베이데이터 유형
여기서 규칙, 참조Varlena가변 크기 데이터). 트리의 내부 데이터 유형이 존재하는 경우
SQL 레벨,스토리지옵션운영자 클래스 생성명령이 될 수 있습니다
사용된. 선택적 8 번째 방법은입니다.거리
, 운영자 클래스 인 경우 필요한 경우
순서 스캔을 지원하기를 원합니다 (가장 가까운 이웃 검색).
일관성
토토 베이 항목 주어진P및 a 쿼리 값Q,이 기능 토토 베이 항목이 |"일관성"쿼리와 함께; 즉, 할 수 있습니다 술어"indexed_column indexable_operator Q"인덱스 항목? 리프 인덱스 항목의 경우 이것은 동일합니다 내부의 경우 인덱스 가능한 조건을 테스트합니다 트리 노드 이것은 스캔 해야하는지 여부를 결정합니다. 트리 노드로 표시되는 인덱스의 하위 트리. 언제 결과는입니다.true, a다시 확인플래그도 반환해야합니다. 이것 술어가 확실히 사실인지를 나타냅니다 아마도 사실입니다. 만약에Recheck=거짓그런 다음 토토 베이가 테스트되었습니다 술어 조건은 정확히 반면다시 확인=True행은 후보 일일뿐입니다. 이 경우 시스템이됩니다 자동으로 평가indexable_operator실제에 대한 실제로 일치하는지 확인하기 위해 값. 이 컨벤션 허용gist지원 무손실 및 손실 토토 베이 구조.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_consistent (내부, data_type, smallint, oid, 내부) Bool을 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_consistent (pg_function_args); 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);
여기,키는 요소입니다 색인 및쿼리가치가 있습니다 색인을 찾았습니다. 그만큼StrategyNumber매개 변수를 나타냅니다 운영자 클래스의 운영자가 적용되고 있습니다. 의 연산자 번호 중 하나와 일치합니다.운영자 클래스 만들기명령. 에 따라 클래스에 포함시킨 운영자, 데이터 유형쿼리연산자이지만 위의 골격은 그렇지 않다고 가정합니다.
Union
이 방법은 트리의 정보를 통합합니다. 주어진 항목 세트,이 기능은 새로운 토토 베이 항목을 생성합니다. 그것은 주어진 모든 항목을 나타냅니다.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_union (내부, 내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_union (pg_function_args); 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지원 방법.
theUnion
구현
함수는 새로 포인터를 반환해야합니다palloc ()
ed 메모리. 당신은 단지 돌아올 수 없습니다
입력이 무엇이든.
compress
데이터 항목을 적합한 형식으로 변환합니다 토토 베이 페이지의 물리적 저장.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_compress (내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_compress (pg_function_args); 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특정 잎을 압축하기 위해 변환중인 유형 물론 노드.
귀하의 요구에 따라 관리해야 할 수도 있습니다. 압축 소개NULL값 거기, 예를 들어 저장(Datum) 0LikeGIST_CIRCLE_COMPRESdoes.
Decompress
반대압축
메소드. 토토 베이를 변환합니다
데이터 항목을 할 수있는 형식으로 표현
데이터베이스에 의해 조작.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_decompress (내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_decompress (pg_function_args); pg_function_info_v1 (my_decompress); 자료 my_decompress (pg_function_args) pg_return_pointer (pg_getarg_pointer (0));
위의 골격은없는 경우에 적합합니다. 감압이 필요합니다.
페널티
값을 나타내는 값을 반환합니다"비용"새 항목을 a에 삽입하는 것
나무의 특정 가지. 항목이 아래로 삽입됩니다
최소한의 경로페널티
in
나무. 값페널티
는 무분별하지 않아야합니다. 경우 a
음수 값이 반환되고 0으로 취급됩니다.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_penalty (내부, 내부, 내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한; - 경우에 따라 페널티 기능이 엄격 할 필요는 없습니다
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_penalty (pg_function_args); 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 (페널티);
the페널티
함수는입니다
인덱스의 우수한 성능에 중요합니다. 사용됩니다
언제 따라야 할 지점을 결정하는 삽입 시간
나무에 새 항목을 추가 할 위치를 선택합니다. 쿼리에서
시간이 더 균형을 잡을수록 더 빨리
조회.
picksplit
색인 페이지가 분할이 필요한 경우이 기능 페이지의 어떤 항목이 기존에 머무를 것인지 결정합니다. 페이지, 그리고 새 페이지로 이동해야합니다.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_picksplit (내부, 내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_picksplit (pg_function_args); pg_function_info_v1 (my_picksplit); 자료 my_picksplit (pg_function_args) gistentRyvector *entryVec = (gistentRyvector *) pg_getarg_pointer (0); OffsetNumber maxoff = EntryVec- n -1; gistentry *ent = EntryVec- 벡터; gist_splitvec *v = (gist_splitvec *) pg_getarg_pointer (1); 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);
좋아요페널티
, Thepicksplit
함수가 중요합니다
색인의 우수한 성능. 적절한 디자인페널티
및picksplit
구현은 어디에 있습니다
잘 실적이 좋은 구현gist인덱스 거짓말.
동일
두 인덱스 항목이 동일하면 false 인 경우 true를 반환합니다 그렇지 않으면.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_same (내부, 내부, 내부) 내부를 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음을 따라갈 수 있습니다. 이 골격 :
Datum my_same (pg_function_args); 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 (결과);
역사적 이유로,동일
함수는 a를 반환하지 않습니다
부울 결과; 대신 깃발을 보관해야합니다
세 번째 인수로 표시된 위치
거리
토토 베이 항목 주어진P및 a 쿼리 값Q,이 기능 토토 베이 항목 결정"거리"쿼리 값에서. 이것 운영자 클래스에 포함 된 경우 기능을 제공해야합니다 모든 주문 연산자. 주문 연산자를 사용하는 쿼리 인덱스 항목을 반환하여 구현됩니다 가장 작은"거리"값 첫째, 결과는 다음과 일치해야합니다 운영자의 의미론. 리프 인덱스 항목의 경우 결과 단지 인덱스 항목까지의 거리를 나타냅니다. for an 내부 트리 노드, 결과는 가장 작아야합니다 어린이 입국이 가질 수있는 거리.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 또는 교체 my_distance (내부, data_type, smallint, oid) float8을 반환합니다 'module_pathname'으로 언어 C 엄격한;
그리고 C 모듈의 일치하는 코드는 다음과 같습니다. 이 골격 :
Datum my_distance (pg_function_args); 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); */ data_type *key = datumgetDatatype (enther- key); 이중 retval; /* * 전략, 키 및 쿼리의 함수로 반환 값을 결정하십시오. */ pg_return_float8 (retval);
에 대한 인수거리
함수와 동일합니다
의 주장일관성
함수 - 재확인 플래그가 사용되지 않는 경우를 제외하고. 거리
잎 지수 항목에 항상 정확히 결정해야합니다.
일단 튜플을 다시 주문할 방법이 없기 때문에
반환. 결정할 때 약간의 근사가 허용됩니다
내부 트리 노드까지의 거리는
결과는 어린이의 실제 거리보다 크지 않습니다.
예를 들어, 경계 상자까지의 거리는 일반적으로
기하학적 응용 분야에서 충분합니다. 결과 값은 할 수 있습니다
유한하다float8값. (무한대
마이너스 무한대는 내부적으로 사용하여 사례를 처리합니다.
Nulls로서 권장하지 않습니다거리
함수를 반환합니다
가치.)
모든 GIST 지원 방법은 일반적으로 호출됩니다 단기간 메모리 컨텍스트; 즉,CurrentMemoryContext각각 이후에 재설정됩니다 튜플이 처리됩니다. 따라서 걱정하는 것은 그리 중요하지 않습니다 당신이 palloc 모든 것을 pfree'ing에 대해. 그러나 경우에 따라 반복 된 데이터를 캐시하는 지원 방법에 유용합니다. 전화. 그렇게하려면 더 긴 수명 데이터를 할당fcinfo- flinfo- fn_mcxt, 포인터를 유지하십시오 그것에fcinfo- flinfo- fn_extra. 이러한 데이터는 인덱스 작업의 수명 (예 : 단일 GIST 인덱스 스캔, 인덱스 빌드 또는 인덱스 튜플 삽입). a를 교체 할 때 이전 값을 pfree에주의하십시오.fn_extra값 또는 누출이 있습니다 작동 기간 동안 축적됩니다.