Postgres에서 부분 인덱스의 조건 인덱싱
Postgres 부분 인덱스 가 Postgres 내부에 저장되는 방법에 대해 추론하려고합니다 . 다음과 같은 색인을 생성한다고 가정 해 보겠습니다.
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 > 1000000
Postgres 는 조건식에 정의 된대로 테이블 order_nr의 하위 집합 에 구축 된 인덱스를 분명히 저장합니다 . 그러나 이와 관련된 몇 가지 질문이 있습니다.ordersbilled is not true
- Postgres
billed is not true는 부분 인덱스와 관련된 행을 빠르게 찾기 위해 내부적으로 다른 인덱스를 저장합니까 ? - (1)이 아닌 경우 별도의 인덱스를 만들면 위의 쿼리가 더 빨리 실행
billed is not true됩니까? (큰 테이블과 몇 개의 행을 사용한다고 가정billed is true)
편집 : 부울 인덱스가 거의 사용되지 않기 때문에 문서를 기반으로 한 내 예제 쿼리가 최고가 아니지만 조건식의 맥락에서 내 질문을 고려하십시오.
답변
B- 트리 인덱스는 각각 테이블의 행에 대한 포인터가있는 인덱스 항목의 순서가 지정된 목록으로 생각할 수 있습니다.
부분 인덱스에서는 목록이 더 작습니다. 조건을 충족하는 행에 대한 인덱스 항목 만 있습니다.
WHERE절에 인덱스 조건이있는 경우 PostgreSQL은 인덱스를 사용할 수 있음을 알고 인덱스 조건이 자동으로 충족되기 때문에 인덱스 조건을 확인할 필요가 없습니다.
그래서:
아니요, 인덱스를 통해 찾은 모든 행은 자동으로 인덱스 조건을 충족하므로 인덱스를 사용하여 만족하는지 확인하는 데 충분합니다.
아니요, 부울 열에 대한 인덱스 는이 부분 인덱스보다 저렴하지 않기 때문에 사용되지 않으며 부분 인덱스를 사용하여 조건을 확인할 수도 있습니다
order_nr.실제로는 그 반대 입니다. 조건을 충족하는 행이 충분하지 않은 경우 조건에
boolean열만있는 쿼리에 부분 인덱스를 사용할 수 있습니다WHERE.
Postgres는 billed사실이 아닌 레코드를 조회하는 데만 사용할 수있는 인덱스를 간단히 구축 할 것입니다. 즉, 결과 B- 트리는에 의해 인덱싱 order_nr되지만 billedfalse 일 때만 원래 테이블로 다시 링크됩니다 .
문서 를 계속 읽으면 인용 한 직후에 다음 쿼리를 예로 볼 수 있습니다.
SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;
Postgres 는 위 쿼리에서 정의한 인덱스를 사용하도록 선택할 수도 있습니다. 색인을 사용하여 전체 색인을 스캔하여이 쿼리를 충족 할 수 있습니다. 아직 청구되지 않은 주문 수가 상대적으로 적은 경우 인덱스를 스캔하는 order_nr것이 전체 테이블 스캔을 수행하는 것보다 선호 될 수 있습니다.
따라서 귀하의 질문 # 1에 대한 대답은 아니요,에 대한 별도의 색인이 없다는 billed것입니다. 대신에 색인은 false로 설정된 order_nr레코드에만 사용할 수 있습니다 billed. 그리고 # 2의 billed is not true경우 청구되지 않은 레코드가 거의 없다고 가정 할 때 두 번째 인덱스를 사용할 수 있습니다. 그러나 현재 색인도 그대로 사용할 수 있습니다.