포스트그레SQL표준 구현 포함브트리(다방향 균형 트리) 인덱스 데이터 구조. 잘 정의된 선형 순서로 정렬될 수 있는 모든 데이터 유형은 btree 인덱스로 색인화될 수 있습니다. 유일한 제한은 색인 항목이 페이지의 약 1/3을 초과할 수 없다는 것입니다(해당되는 경우 TOAST 압축 후).
각 btree 연산자 클래스는 데이터 유형에 정렬 순서를 부과하기 때문에 btree 연산자 클래스(또는 실제로 연산자 계열)는 다음과 같이 사용됩니다.포스트그레SQL의 일반적인 표현과 정렬 의미론에 대한 이해. 따라서 그들은 단지 btree 인덱스를 지원하는 데 필요한 것 이상의 일부 기능과 btree와 상당히 거리가 먼 시스템 부분을 획득했습니다.오전그것들을 활용하세요.
표시된 바와 같이표 36.3, btree 연산자 클래스는 5개의 비교 연산자를 제공해야 합니다.<, <=, =, =그리고. 그렇게 예상할 수도 있겠네요<또한 연산자 클래스의 일부여야 하지만 그렇지 않습니다. 왜냐하면 a를 사용하는 것은 거의 유용하지 않기 때문입니다.<색인 검색의 WHERE 절입니다. (일부 목적에 따라 기획자가 처리합니다.<btree 연산자 클래스와 연관됨; 하지만를 통해 해당 연산자를 찾습니다.=from이 아닌 연산자의 부정자 링크pg_amop.)
여러 데이터 유형이 거의 동일한 정렬 의미를 공유하는 경우 해당 연산자 클래스를 연산자 계열로 그룹화할 수 있습니다. 그렇게 하면 기획자가 유형 간 비교에 대해 추론을 할 수 있으므로 유리합니다. 계열 내의 각 연산자 클래스에는 입력 데이터 유형에 대한 단일 유형 연산자(및 관련 지원 함수)가 포함되어야 하며, 교차 유형 비교 연산자 및 지원 함수는 다음과 같습니다.“느슨한”가족에서. 교차 유형 연산자의 전체 세트가 패밀리에 포함되어 플래너가 전이성에서 추론한 모든 비교 조건을 나타낼 수 있도록 하는 것이 좋습니다.
btree 연산자 계열이 충족해야 하는 몇 가지 기본 가정이 있습니다.
안=연산자는 동등 관계여야 합니다. 즉, null이 아닌 모든 값에 대해A, B, C데이터 유형:
A = A참입니다(반사법)
ifA = B그러면B = A (대칭법칙)
ifA = B그리고B = C그러면A = C (이행법칙)
A <연산자는 강력한 순서 관계여야 합니다. 즉, null이 아닌 모든 값에 대해A, B, C:
A < A거짓입니다(비반사적 법칙)
ifA < B그리고B < C그러면A < C (이행법칙)
또한 주문은 전체입니다. 즉, null이 아닌 모든 값에 대해A, B:
정확히 다음 중 하나A < B, A = B및B < A참입니다(삼분법법)
(물론 삼분법 법칙은 비교 지원 함수의 정의를 정당화합니다.)
다른 세 연산자는 다음과 같이 정의됩니다.=그리고<명백한 방식으로 행동해야 하며 그들과 일관되게 행동해야 합니다.
여러 데이터 유형을 지원하는 연산자 계열의 경우 위의 법칙은 다음과 같은 경우에 적용되어야 합니다.A, B, C은 계열의 모든 데이터 유형에서 가져옵니다. 전이법칙은 교차 유형 상황에서 두세 가지 다른 연산자의 동작이 일관적이라는 진술을 나타내기 때문에 보장하기 가장 까다롭습니다. 예를 들어 다음과 같이 입력하면 작동하지 않습니다.float8그리고숫자적어도 현재 의미론으로는 그렇지 않은 동일한 연산자 계열로숫자값은 다음으로 변환됩니다.float8a와 비교를 위해float8. 제한된 정확성으로 인해float8, 이는 별개의 항목이 있음을 의미합니다.숫자동일하게 비교될 값float8값이므로 추이법칙은 실패합니다.
다중 데이터 유형 계열에 대한 또 다른 요구 사항은 연산자 계열에 포함된 데이터 유형 간에 정의된 암시적 또는 이진 강제 변환이 관련 정렬 순서를 변경해서는 안 된다는 것입니다.
btree 인덱스가 이러한 법칙을 단일 데이터 유형 내에서 유지하도록 요구하는 이유는 상당히 명확해야 합니다. 이러한 법칙이 없으면 키를 정렬할 순서가 없습니다. 또한 다른 데이터 유형의 비교 키를 사용하는 인덱스 검색에서는 두 데이터 유형에 걸쳐 제대로 작동하려면 비교가 필요합니다. 패밀리 내의 세 개 이상의 데이터 유형에 대한 확장은 btree 인덱스 메커니즘 자체에서 엄격히 요구되지는 않지만 플래너는 최적화 목적으로 이를 사용합니다.
그림과 같이표 36.9, btree는 1개의 필수 지원 기능과 5개의 선택적 지원 기능을 정의합니다. 6가지 사용자 정의 메서드는 다음과 같습니다.
주문btree 연산자 계열이 비교 연산자를 제공하는 데이터 유형의 각 조합에 대해 다음에 등록된 비교 지원 기능을 제공해야 합니다.pg_amproc지원 기능 번호 1 및amproclefttype/amprorighttype비교를 위한 왼쪽 및 오른쪽 데이터 유형과 동일(즉, 일치하는 연산자가 등록된 동일한 데이터 유형pg_amop). 비교 함수는 null이 아닌 두 개의 값을 취해야 합니다.A그리고B그리고 반환int32값은< 0, 0또는 0언제A < B, A = B, 또는A B입니다. Null 결과는 허용되지 않습니다. 데이터 유형의 모든 값은 비교할 수 있어야 합니다. 참조src/backend/access/nbtree/nbtcompare.c예를 들어.
비교된 값이 조합 가능한 데이터 유형인 경우 표준을 사용하여 적절한 조합 OID가 비교 지원 함수에 전달됩니다.PG_GET_COLLATION()메커니즘.
정렬지원선택적으로 btree 연산자 계열이 제공할 수 있습니다.정렬 지원함수, 지원 함수 번호 2에 등록되어 있습니다. 이 함수를 사용하면 순진하게 비교 지원 함수를 호출하는 것보다 더 효율적인 방법으로 정렬 목적으로 비교를 구현할 수 있습니다. 이에 관련된 API는 다음에서 정의됩니다.src/include/utils/sortsupport.h.
범위 내선택적으로 btree 운영자 제품군이 제공할 수 있음범위 내지원 기능, 지원 기능 번호 3에 등록되어 있습니다. 이는 btree 인덱스 작업 중에는 사용되지 않습니다. 오히려 연산자 계열의 의미를 확장하여를 포함하는 창 절을 지원할 수 있습니다.범위 오프셋 이전그리고범위 오프셋 다음프레임 경계 유형(참조섹션 4.2.8). 기본적으로 제공되는 추가 정보는 를 더하거나 빼는 방법입니다.오프셋가족의 데이터 순서와 호환되는 방식으로 값을 지정합니다.
안범위 내함수에는 서명이 있어야 합니다
범위 내(발유형1,베이스유형1,오프셋유형2,하위부울,적음부울) 부울을 반환합니다
발그리고베이스연산자 계열에서 지원하는 유형 중 하나인 동일한 유형이어야 합니다(즉, 순서를 제공하는 유형). 그러나오프셋다른 유형일 수 있으며, 이는 가족이 지원하지 않는 유형일 수 있습니다. 예를 들어 내장된time_ops가족은 다음을 제공합니다범위 내함수오프셋유형간격. 가족이 제공할 수 있습니다.범위 내지원되는 유형 및 하나 이상의 기능오프셋유형. 각각범위 내함수를 입력해야 합니다pg_amproc함께amproclefttype같음유형1그리고amprorighttype같음유형2.
an의 필수 의미론범위 내함수는 두 개의 부울 플래그 매개변수에 따라 달라집니다. 더하거나 빼야 합니다베이스그리고오프셋그런 다음 비교발결과에 다음과 같이 표시됩니다:
if!하위그리고!적음, 복귀발 = (베이스 + 오프셋)
if!하위그리고적음, 복귀발 <= (베이스 + 오프셋)
if하위그리고!적음, 복귀발 = (베이스 - 오프셋)
if하위그리고적음, 복귀발 <= (베이스 - 오프셋)
그렇게 하기 전에 함수는 다음의 부호를 확인해야 합니다.오프셋: 0보다 작으면 오류 발생ERRCODE_INVALID_PRECEDING_OR_FOLLOWING_SIZE(22013)과 같은 오류 텍스트 포함“창 함수의 이전 또는 다음 크기가 잘못되었습니다.”. (비표준 연산자 계열은 의미상 필요성이 거의 없어 이 제한을 무시할 수도 있지만 이는 SQL 표준에서 요구됩니다.) 이 요구 사항은 다음으로 위임됩니다.범위 내핵심 코드가 무엇을 이해할 필요가 없도록 함수“0보다 작음”특정 데이터 유형을 의미합니다.
추가적인 기대는 다음과 같습니다.범위 내함수는 가능하다면 오류 발생을 피해야 합니다.베이스 + 오프셋또는베이스 - 오프셋오버플로될 것입니다. 해당 값이 데이터 유형의 범위를 벗어나더라도 올바른 비교 결과를 확인할 수 있습니다. 데이터 유형에 다음과 같은 개념이 포함되어 있는 경우 주의하세요.“무한대”또는“NaN”, 이를 보장하려면 특별한 주의가 필요할 수 있습니다.범위 내의 결과는 연산자 계열의 일반적인 정렬 순서와 일치합니다.
의 결과범위 내함수는 연산자 계열이 적용한 정렬 순서와 일치해야 합니다. 정확하게 말하자면, 고정된 값이 주어지면오프셋그리고하위, 다음:
만약범위 내와적음= 일부에게는 true가 true임발1그리고베이스, 모든 경우에 해당되어야 합니다.발2 <= 발1동일하게베이스.
만약범위 내와적음= 일부에게는 true가 false임발1그리고베이스, 모든 경우에 대해 false여야 합니다.발2 = val1동일하게베이스.
만약범위 내함께적음= 일부에게는 true가 true임발그리고베이스1, 모든 경우에 해당되어야 합니다.base2 = 베이스1동일하게발.
만약범위 내와적음= 일부에게는 true가 false임발그리고베이스1, 모든 경우에 대해 false여야 합니다.베이스2 <= 베이스1동일하게발.
조건이 반전된 유사한 진술은 다음과 같은 경우에 유지됩니다.적음= 거짓.
주문되는 유형(유형1)이 조합 가능하면 적절한 조합 OID가에 전달됩니다.범위 내함수, 표준 PG_GET_COLLATION() 메커니즘을 사용합니다.
범위 내함수는 NULL 입력을 처리할 필요가 없으며 일반적으로 엄격으로 표시됩니다.
equalimage선택적으로 btree 운영자 제품군이 제공할 수 있습니다.equalimage (“동일성은 이미지 평등을 의미합니다.”) 지원 함수는 지원 함수 번호 4에 등록되어 있습니다. 이러한 함수를 통해 핵심 코드는 btree 중복 제거 최적화를 적용하는 것이 안전한 시기를 결정할 수 있습니다. 현재,equalimage함수는 색인을 구축하거나 재구축할 때만 호출됩니다.
안equalimage함수에는 서명이 있어야 합니다
동일이미지(opcintypeoid)은 부울을 반환합니다.
반환 값은 연산자 클래스 및 데이터 정렬에 대한 정적 정보입니다. 돌아오는 중참다음을 나타냅니다.주문연산자 클래스에 대한 함수는 반환만 보장됩니다.0 (“인수는 동일합니다”) 언제A그리고B인수는 의미 정보의 손실 없이 상호 교환 가능합니다. 등록하지 않음equalimage함수 또는 반환거짓이 조건이 유지될 수 없다고 가정할 수 없음을 나타냅니다.
그opcintype인수는연산자 클래스가 색인화하는 데이터 유형입니다. 이는 동일한 기본 요소를 재사용할 수 있는 편리함입니다.pg_type.oidequalimage연산자 클래스 전반에 걸쳐 함수를 사용합니다. 만일opcintype은 조합 가능한 데이터 유형이므로 적절한 조합 OID가 다음으로 전달됩니다.equalimage함수, 표준 사용PG_GET_COLLATION()메커니즘.
연산자 클래스에 관한 한 반환참중복 제거가 안전함을 나타냅니다(또는 OID가 전달된 데이터 정렬에 대해 안전함을 나타냅니다.equalimage함수). 그러나 핵심 코드는 다음 경우에만 인덱스에 대해 중복 제거가 안전한 것으로 간주합니다.모든인덱싱된 열은 다음을 등록하는 연산자 클래스를 사용합니다.equalimage함수, 각 함수는 실제로 반환참호출될 때.
이미지 평등은거의간단한 비트 동등성과 동일한 조건입니다. 한 가지 미묘한 차이점이 있습니다. varlena 데이터 유형을 인덱싱할 때 두 이미지 동일 데이텀의 디스크상 표현은 일관되지 않은 적용으로 인해 비트 단위로 동일하지 않을 수 있습니다.토스트입력 시 압축. 공식적으로 연산자 클래스의equalimage함수 반환참, 다음과 같이 가정하는 것이 안전합니다.datum_image_eq()C 함수는 항상 연산자 클래스의 함수와 일치합니다.주문함수(동일한 데이터 정렬 OID가 두 가지 모두에 전달되는 경우equalimage그리고주문함수).
핵심 코드는 근본적으로 다음에 대해 아무것도 추론할 수 없습니다.“동일성은 이미지 평등을 의미합니다.”동일한 계열에 있는 다른 연산자 클래스의 세부정보를 기반으로 하는 다중 데이터 유형 계열 내의 연산자 클래스 상태. 또한, 사업자군이 교차형을 등록하는 것은 타당하지 않습니다.equalimage함수를 실행하려고 시도하면 오류가 발생합니다. 그 이유는“동일성은 이미지 평등을 의미합니다.”상태는 연산자 계열 수준에서 어느 정도 정의되는 정렬/동등 의미 체계에만 의존하지 않습니다. 일반적으로 하나의 특정 데이터 유형이 구현하는 의미는 별도로 고려해야 합니다.
코어에 포함된 연산자 클래스가 따르는 규칙PostgreSQL유통은 주식을 등록하는 것입니다, 일반equalimage함수. 대부분의 연산자 클래스가 등록됩니다.btequalimage(), 이는 중복 제거가 무조건 안전함을 나타냅니다. 다음과 같은 조합 가능한 데이터 유형에 대한 연산자 클래스텍스트등록btvarstrequalimage(), 이는 결정적 데이터 정렬을 사용하면 중복 제거가 안전함을 나타냅니다. 타사 확장 프로그램의 모범 사례는 자체 맞춤 기능을 등록하여 제어권을 유지하는 것입니다.
옵션선택적으로 토토트리 연산자 제품군이 제공할 수 있습니다.옵션 (“연산자 클래스 특정 옵션”) 지원 함수는 지원 함수 번호 5에 등록되어 있습니다. 이러한 함수는 연산자 클래스 동작을 제어하는 사용자에게 표시되는 매개변수 집합을 정의합니다.
안옵션지원 기능에는 서명이 있어야 합니다
옵션(재이동local_relopts *)는 void를 반환합니다.
함수는 a에 대한 포인터를 전달받습니다.local_reloptsstruct, 연산자 클래스별 옵션 세트로 채워져야 합니다. 옵션은를 사용하여 다른 지원 기능에서 액세스할 수 있습니다.PG_HAS_OPCLASS_OPTIONS()그리고PG_GET_OPCLASS_OPTIONS()매크로.
현재 B-Tree 연산자 클래스에는옵션지원 기능. B-트리는 GiST, SP-GiST, GIN 및 BRIN과 같은 키의 유연한 표현을 허용하지 않습니다. 그래서,옵션아마도 현재 B-트리 인덱스 액세스 방법에는 그다지 적용되지 않을 것입니다. 그럼에도 불구하고, 이 지원 기능은 통일성을 위해 B-트리에 추가되었으며 아마도 다음 B-트리가 진화하는 동안 사용될 것입니다.PostgreSQL.
지원 건너뛰기선택적으로, btree 연산자 계열은 다음을 제공할 수 있습니다.지원 건너뛰기함수, 지원 함수 번호 6에 등록됨. 이러한 함수는 B-트리 코드에 연산자 클래스의 기본 입력 유형으로 표시될 수 있는 모든 가능한 값을 키 공간 순서로 반복하는 방법을 제공합니다. 이는 건너뛰기 스캔 최적화를 적용할 때 핵심 코드에서 사용됩니다. 이에 관련된 API는 다음에서 정의됩니다.src/include/utils/skipsupport.h.
건너뛰기 지원 기능을 제공하지 않는 연산자 클래스는 여전히 건너뛰기 스캔을 사용할 수 있습니다. 핵심 코드는 여전히 대체 전략을 사용할 수 있지만 일부 개별 유형에서는 이것이 차선책일 수 있습니다. 일반적으로 연속 유형의 연산자 클래스가 건너뛰기 지원 기능을 제공하는 것은 의미가 없으며 실현 가능하지 않을 수도 있습니다.
운영자 계열이 교차 유형을 등록하는 것은 합리적이지 않습니다.지원 건너뛰기기능을 수행하려고 시도하면 오류가 발생합니다. 이는 인덱스 튜플에서 복사된 값을 증가시켜 다음 인덱스 가능한 값을 결정해야 하기 때문입니다. 생성된 값은 모두 동일한 기본 데이터 유형이어야 합니다(“건너뛰었습니다”색인 열의 opclass 입력 유형).
이 섹션은 고급 사용자에게 유용할 수 있는 토토트리 인덱스 구현 세부사항을 다룹니다. 참조src/백엔드/액세스/nbtree/README토토Tree 구현에 대한 훨씬 더 자세한 내부 중심 설명을 보려면 소스 배포판을 참조하세요.
PostgreSQLB-트리 인덱스는 다중 레벨 트리 구조로, 트리의 각 레벨은 이중으로 연결된 페이지 목록으로 사용될 수 있습니다. 단일 메타페이지는 인덱스의 첫 번째 세그먼트 파일 시작 부분에 있는 고정 위치에 저장됩니다. 다른 모든 페이지는 리프 페이지이거나 내부 페이지입니다. 리프 페이지는 트리의 가장 낮은 수준에 있는 페이지입니다. 다른 모든 레벨은 내부 페이지로 구성됩니다. 각 리프 페이지에는 테이블 행을 가리키는 튜플이 포함되어 있습니다. 각 내부 페이지에는 트리의 다음 수준을 가리키는 튜플이 포함되어 있습니다. 일반적으로 모든 페이지의 99% 이상이 리프 페이지입니다. 내부 페이지와 리프 페이지 모두에 설명된 표준 페이지 형식을 사용합니다.PostgreSQL : 문서 : 17 : 65.6. 데이터베이스 토토 베이 레이아웃.
기존 리프 페이지가 들어오는 튜플에 맞지 않을 때 새로운 리프 페이지가 토토트리 색인에 추가됩니다. 갑페이지 분할작업은 항목의 일부를 새 페이지로 이동하여 원래 오버플로된 페이지에 속했던 항목을 위한 공간을 만듭니다. 페이지 분할에는 새도 삽입해야 합니다.다운링크상위 페이지의 새 페이지로 이동하면 상위 페이지가 차례로 분할될 수 있습니다. 페이지 분할“계단식 위쪽으로”재귀적인 방식으로. 루트 페이지가 마침내 새로운 다운링크에 맞지 않을 때, a루트 페이지 분할작동이 발생합니다. 이렇게 하면 원래 루트 페이지보다 한 수준 높은 새 루트 페이지를 생성하여 트리 구조에 새 수준을 추가합니다.
토토트리 인덱스는 MVCC에 동일한 논리 테이블 행의 여러 기존 버전이 있을 수 있다는 사실을 직접 인식하지 못합니다. 인덱스에 대한 각 튜플은 자체 인덱스 항목이 필요한 독립 객체입니다.“버전 변동”튜플은 때때로 누적되어 쿼리 지연 시간 및 처리량에 부정적인 영향을 미칠 수 있습니다. 이는 일반적으로 다음과 같은 경우에 발생합니다.업데이트-대부분의 개별 업데이트가 적용할 수 없는 과중한 작업 부하핫최적화.중 하나의 색인에 포함된 단 하나의 열 값 변경업데이트 항상새로운 인덱스 튜플 세트가 필요합니다 — 하나는각각 모두테이블의 색인입니다. 특히 여기에는 그렇지 않은 인덱스가 포함되어 있습니다.“논리적으로 수정됨”by the업데이트. 모든 인덱스에는 테이블의 최신 버전을 가리키는 후속 실제 인덱스 튜플이 필요합니다. 각 인덱스 내의 각각의 새로운 튜플은 일반적으로 원본과 공존해야 합니다.“업데이트됨”짧은 기간 동안 튜플(일반적으로 다음 직후까지업데이트트랜잭션 커밋).
B-트리 인덱스는 다음을 수행하여 버전 변동 인덱스 튜플을 점진적으로 삭제합니다.상향식 색인 삭제통과합니다. 각 삭제 패스는 예상되는 조치에 반응하여 트리거됩니다.“버전 변동 페이지 분할”. 이는 논리적으로 수정되지 않은 인덱스에서만 발생합니다.업데이트문, 그렇지 않으면 특정 페이지에 사용되지 않는 버전이 집중적으로 축적되는 경우가 발생합니다. 페이지 분할은 일반적으로 피할 수 있지만, 특정 구현 수준의 휴리스틱이 하나의 가비지 인덱스 튜플도 식별하고 삭제하지 못할 가능성이 있습니다(이 경우 페이지 분할 또는 중복 제거 단계는 들어오는 새 튜플이 리프 페이지에 맞지 않는 문제를 해결합니다). 단일 논리 행에 대해 인덱스 스캔이 통과해야 하는 최악의 버전 수는 전체 시스템 응답성과 처리량에 중요한 영향을 미칩니다. 상향식 인덱스 삭제 단계는 다음을 기반으로 단일 리프 페이지에서 의심되는 가비지 튜플을 대상으로 합니다.정성적논리적 행 및 버전과 관련된 구별. 이는 다음과 대조됩니다.“하향식”autovacuum 작업자가 수행하는 인덱스 정리(확실할 때 트리거됨)정량적테이블 수준 임계값이 초과되었습니다(참조섹션 24.1.6).
B-트리 인덱스 내에서 수행되는 모든 삭제 작업이 상향식 삭제 작업은 아닙니다. 인덱스 튜플 삭제에는 고유한 범주가 있습니다.간단한 인덱스 튜플 삭제. 이는 삭제해도 안전한 것으로 알려진 인덱스 튜플(항목 식별자의 튜플)을 삭제하는 지연된 유지 관리 작업입니다.LP_DEAD비트가 이미 설정되어 있습니다). 상향식 인덱스 삭제와 마찬가지로 단순 인덱스 삭제는 분할을 피하기 위한 방법으로 페이지 분할이 예상되는 시점에 발생합니다.
단순 삭제는 최근 색인 스캔이 설정된 경우에만 발생할 수 있다는 점에서 기회주의적입니다.LP_DEAD영향을 받은 항목이 지나가고 있습니다. 이전에PostgreSQL14, B-Tree 삭제의 유일한 범주는 단순 삭제였습니다. 상향식 삭제와 주요 차이점은 전자만이 인덱스 스캔을 통과하는 활동에 의해 기회에 따라 구동되는 반면 후자만이 구체적으로 버전 변동을 목표로 한다는 것입니다.업데이트인덱싱된 열을 논리적으로 수정하지 않는 것입니다.
상향식 인덱스 삭제는 특정 작업 부하가 있는 특정 인덱스에 대한 모든 가비지 인덱스 튜플 정리의 대부분을 수행합니다. 이는 상당한 버전 변동이 발생할 수 있는 모든 B-Tree 인덱스에서 예상되는 현상입니다.업데이트s는 인덱스가 포함하는 열을 논리적으로 거의 또는 전혀 수정하지 않습니다. 논리적 행당 평균 및 최악의 경우 버전 수는 대상 증분 삭제 단계를 통해서만 낮게 유지될 수 있습니다. 그럼에도 불구하고 특정 인덱스의 디스크 크기는 단일 페이지/블록 하나도 증가하지 않을 가능성이 높습니다.상수버전 변동:업데이트s. 그럼에도 불구하고 철저한“깨끗한 청소”작성자:진공작업(일반적으로 자동 진공 작업자 프로세스에서 실행)은 결국 다음 작업의 일부로 필요하게 됩니다.집단테이블과 각 인덱스 정리.
달리진공, 상향식 인덱스 삭제는 가장 오래된 가비지 인덱스 튜플이 얼마나 오래되었는지에 대한 강력한 보장을 제공하지 않습니다. 인덱스 보유를 허용할 수 없습니다.“떠다니는 쓰레기”테이블과 해당 인덱스 전체가 공유하는 보수적 구분점 이전에 죽은 인덱스 튜플. 이 기본적인 테이블 수준 불변성은 테이블을 안전하게 재활용할 수 있게 해줍니다.TIDs. 이는 서로 다른 논리적 행이 동일한 테이블을 재사용하는 것이 가능한 방법입니다.TID시간 경과에 따라(수명 기간이 동일한 두 개의 논리적 행에서는 결코 이런 일이 발생하지 않지만진공주기).
중복은 리프 페이지 튜플(테이블 행을 가리키는 튜플)입니다.모두인덱싱된 키 열에는 동일한 인덱스에 있는 하나 이상의 다른 리프 페이지 튜플의 해당 열 값과 일치하는 값이 있습니다. 중복 튜플은 실제로 매우 일반적입니다. 토토트리 인덱스는 선택적 기술이 활성화된 경우 중복에 대해 특별하고 공간 효율적인 표현을 사용할 수 있습니다.중복 제거.
중복 제거는 중복된 튜플 그룹을 주기적으로 병합하여 단일을 형성함으로써 작동합니다.게시 목록각 그룹에 대한 튜플. 열 키 값은 이 표현에서 한 번만 나타납니다. 그 다음에는 정렬된 배열이 옵니다.TID47394_47765
B-Tree 중복 제거는 다음과 같이 효과적입니다.“중복”NULL 값이 포함되어 있지만 NULL 값은 다음에 따라 결코 서로 동일하지 않습니다.=토토트리 연산자 클래스의 구성원. 온디스크 토토트리 구조를 이해하는 구현 부분에 관한 한 NULL은 인덱스 값 도메인의 또 다른 값일 뿐입니다.
중복 제거 프로세스는 기존 리프 페이지에 맞지 않는 새 항목이 삽입될 때 느리게 발생합니다. 단, 색인 튜플 삭제로 새 항목을 위한 충분한 공간을 확보할 수 없는 경우에만 가능합니다(일반적으로 삭제를 잠시 고려한 후 건너뜁니다). GIN 게시 목록 튜플과 달리 B-Tree 게시 목록 튜플은 새 복제본이 삽입될 때마다 확장할 필요가 없습니다. 이는 단지 리프 페이지의 원래 논리적 내용을 대체하는 물리적 표현일 뿐입니다. 이 설계는 혼합된 읽기-쓰기 워크로드에서 일관된 성능을 우선시합니다. 대부분의 클라이언트 애플리케이션은 중복 제거를 사용하면 최소한 중간 정도의 성능 이점을 얻을 수 있습니다. 중복 제거는 기본적으로 활성화되어 있습니다.
색인 생성그리고REINDEX중복 제거를 적용하여 게시 목록 튜플을 생성합니다. 그러나 사용하는 전략은 약간 다릅니다. 테이블에서 가져온 정렬된 입력에서 발견된 중복 일반 튜플의 각 그룹은 게시 목록 튜플로 병합됩니다.이전현재 보류 중인 리프 페이지에 추가 중입니다. 개별 게시 목록 튜플은 여러 개로 구성됩니다.TID49530_49665색인 생성그리고REINDEX일회성 일괄 작업이기 때문입니다.
인덱스에 중복 값이 거의 없거나 전혀 없기 때문에 중복 제거의 이점을 누리지 못하는 쓰기 중심 작업 부하는 중복 제거가 명시적으로 비활성화되지 않는 한 작고 고정된 성능 저하를 초래합니다.deduplicate_items저장 매개변수를 사용하여 개별 색인 내에서 중복 제거를 비활성화할 수 있습니다. 게시 목록 튜플을 읽는 것은 적어도 표준 튜플 표현을 읽는 것만큼 효율적이므로 읽기 전용 워크로드에서는 성능 저하가 전혀 없습니다. 중복 제거를 비활성화하는 것은 일반적으로 도움이 되지 않습니다.
때때로 고유 색인(고유 제약 조건 포함)에서 중복 제거를 사용할 수 있습니다. 이를 통해 리프 페이지는 일시적으로 허용됩니다.“흡수”추가 버전 이탈이 중복되었습니다. 고유 인덱스의 중복 제거는 특히 장기 실행 트랜잭션이 가비지 수집을 차단하는 스냅샷을 보유하는 경우 상향식 인덱스 삭제를 증가시킵니다. 목표는 상향식 지수 삭제 전략이 다시 효과적일 때까지 시간을 벌기 위한 것입니다. 단일 장기 실행 트랜잭션이 자연스럽게 사라질 때까지 페이지 분할을 지연하면 이전 삭제 단계가 실패한 경우 상향식 삭제 단계가 성공할 수 있습니다.
고유 인덱스의 중복 제거 패스가 발생해야 하는지 여부를 결정하기 위해 특별한 경험적 방법이 적용됩니다. 종종 리프 페이지 분할로 바로 건너뛰어 도움이 되지 않는 중복 제거 단계의 주기 낭비로 인한 성능 저하를 방지할 수 있습니다. 중복 제거 오버헤드가 우려된다면 설정을 고려하세요.deduplicate_items = 꺼짐선택적으로. 고유 색인에서 중복 제거를 활성화하면 단점이 거의 없습니다.
구현 수준 제한으로 인해 모든 경우에 중복 제거를 사용할 수는 없습니다. 중복 제거 안전성은 다음과 같은 경우에 결정됩니다.색인 생성또는REINDEX실행되었습니다.
중복 제거는 안전하지 않은 것으로 간주되며 동일한 데이텀 간에 의미상 중요한 차이가 있는 다음과 같은 경우에는 사용할 수 없습니다.
텍스트, var토토ar및문자다음의 경우 중복 제거를 사용할 수 없습니다.비결정적조합이 사용됩니다. 대소문자 및 악센트 차이는 동일한 데이텀 간에 유지되어야 합니다.
숫자중복 제거를 사용할 수 없습니다. 숫자 표시 배율은 동일한 데이텀 간에 유지되어야 합니다.
jsonb중복 제거를 사용할 수 없습니다.jsonb토토트리 연산자 클래스 사용숫자내부적으로.
float4그리고float8중복 제거를 사용할 수 없습니다. 이러한 유형에는 다음과 같은 고유한 표현이 있습니다.-0그리고0그럼에도 불구하고 이는 동일한 것으로 간주됩니다. 이 차이는 보존되어야 합니다.
향후 버전에서 해제될 수 있는 구현 수준 제한이 하나 더 있습니다.PostgreSQL:
컨테이너 유형(예: 복합 유형, 배열 또는 범위 유형)은 중복 제거를 사용할 수 없습니다.
사용된 연산자 클래스 또는 데이터 정렬에 관계없이 적용되는 구현 수준 제한이 하나 더 있습니다:
포함색인은 중복 제거를 사용할 수 없습니다.
문서에 올바르지 않은 내용이 있으면 일치하지 않습니다. 특정 기능에 대한 경험이 있거나 추가 설명이 필요한 경우 이용해주세요이 양식문서 문제를 보고합니다.