복합 색인도 첫 번째 필드의 쿼리에도 적합합니까?


86

이 전 필드가있는 테이블이 있다고 가정 해 봅시다 AB. 나는 A+ 에 대해 정기적 인 쿼리를 B하므로에 복합 인덱스를 만들었습니다 (A,B). A복합 인덱스 만으로도 쿼리 가 완전히 최적화됩니까?

또한에 인덱스를 A만들었지 만 Postgres는 여전히에 대해서만 복합 인덱스를 쿼리에 사용합니다 A. 이전 답변이 긍정적이라면 실제로 중요하지 않다고 생각하지만 단일 A인덱스를 사용할 수있는 경우 기본적으로 복합 인덱스를 선택하는 이유는 무엇입니까?


나는 이것을 위해 작은 테스트를 설정하려고했습니다. 그러나 필자의 경우 두 열 인덱스는 단일 열 인덱스를 삭제했을 때만 사용되었으며 처음 생성 된 인덱스와 관련이 없습니다. 두 열 인덱스를 먼저 만든 경우 초기 계획에서 비트 맵 힙 스캔을 사용했다는 것이 흥미 롭습니다. 1 열 인덱스를 생성 한 다음 쿼리 (사용 된 인덱스 스캔)를 실행하고 새로 생성 된 인덱스를 삭제하면 2 열 인덱스와 관련된 계획이 인덱스 스캔으로 전환됩니다.
dezso

@dezso 흥미로운. 각 쿼리에 대한 비용은 어디에 있습니까?
Luciano

비트 맵 인덱스 스캔 비용 : 107.98, 43ms 실행 시간 인덱스 스캔 1 열 : 비용 8.69, 2 열 : 43.69. 실행 시간은 크게 다르지 않습니다 (변동이 둘 사이의 차이보다 큽니다).
dezso

@Luciano explain analyze및 텍스트 를 표시 할 수 있습니까 ?
Craig Ringer

답변:


88

확실합니다. 우리는이 관련 질문에 대해 자세히 설명했습니다.

공간은의 배수로 할당 MAXALIGN되는데, 일반적으로 64 비트 OS에서는 8 바이트, 32 비트 OS에서는 4 바이트입니다. 확실하지 않은 경우 확인하십시오 pg_controldata. 또한 인덱스 열의 데이터 유형 (일부 정렬 패딩이 필요함) 및 실제 내용에 따라 다릅니다.

예를 들어, 두 개의 integer열 (각 4 바이트) 의 인덱스는 일반적으로 하나의 인덱스만큼 정확하게 커지므로 다른 4 바이트는 정렬 패딩에 손실됩니다.

이 경우 쿼리 플래너가 인덱스와 인덱스를 (a,b)비교할 때 실제로 단점이 없습니다 (a). 그리고 일반적으로 여러 쿼리가 동일한 인덱스를 사용하는 것이 좋습니다. 공유시 (또는 일부) 캐시에 (빠른) 캐시에 상주 할 가능성이 높아집니다.

이미에 인덱스를 유지 관리하고 있다면 인덱스 가 상당히 작지 않은 한 (a,b)다른 인덱스를 만드는 것은 의미가 없습니다 . 동일은 하지 마찬가지 대 . 자세한 내용은 첫 번째 줄의 링크를 따르십시오.(a)(b,a)(a)

반대 방향에서 오는 경우와 같은 추가 색인이 필요한 경우 가능한 경우 (a,b)기존 색인을 삭제하는 (a)것이 좋습니다. PK 또는 UNIQUE제약 조건 의 색인이므로 종종 불가능합니다 . Postgres 11부터는 절을 사용 b하여 제약 조건 정의에 추가 하는 것만으로도 벗어날 수 있습니다 INCLUDE. 매뉴얼의 세부 사항.

또는(b,a) 쿼리를 b추가로 추가 하기 위해 대신 새 인덱스를 작성하십시오 . 동등 조건에 대해서만 btree 인덱스의 인덱스 표현식 순서는 중요하지 않습니다. 그러나 범위 조건과 관련된 경우에는 그렇게합니다. 보다:

정렬 패딩에 손실 된 공간 만 사용하더라도 인덱스에 추가 열을 포함시키는 경우 잠재적 단점 이 있습니다 .

  • 추가 열이 업데이트 될 때마다 인덱스도 업데이트해야하므로 쓰기 작업에 비용이 추가되고 인덱스 팽창이 증가 할 수 있습니다.
  • 인덱스 열이 관련되어 있으면 테이블의 HOT 업데이트 (힙만 튜플)가 불가능합니다 .

HOT 업데이트에 대한 추가 정보 :

물체 크기를 측정하는 방법 :


1
A 열에 인덱스가 있고 복합 인덱스 (A, B)를 추가해야하는 경우 인덱스 A를 삭제해야한다고이 값을 확장 할 수 있습니까? 인덱스를 재사용하는 것은 캐시의 효율성 등을 향상 경우 (A, B) 완전히 최적화, A는, 그것은에 추가 인덱스처럼 보이는 공간과 잠재적으로 느린 것을 아래로 낭비 것
jvans

1
@jvans : 눈에 띄는 예외 및 대안과 함께 일반적으로 true입니다. 그 문제를 해결하기 위해 단락을 추가했습니다.
Erwin Brandstetter

2

귀하의 질문에 따르면 필드 A와 B가있는 테이블이 있습니다.

SELECT * FROM [YOUR TBL]
WHERE A='XXXX'

Optimizer는 추출 임의 액세스를 피하기 위해 복합 인덱스를 선택합니다!


-4

술어에서 첫 번째만을 사용하는 경우입니다.

복합 키의 첫 번째 열과 복합 키의 비열을 사용하면 스캔합니다.

그것을 속이려면 다음과 같은 더미 술어를 키가 아닌 열로 만들 수 있습니다.

[A, B]는 색인입니다. [C]-다른 열

인덱스를 활용하려면 다음과 같이 작성하십시오.

SELECT
    A,B,C,D,E
FROM 
    test
WHERE
   A=1
AND
   B=B
AND 
   C=3

... 단일 A 인덱스를 사용할 수있는 경우 기본적으로 복합 인덱스를 선택하는 이유는 무엇입니까?

하나 또는 두 개의 술어 [A] 또는 [A], [B]가있는 경우에만 인덱스를 사용합니다. [B], [A] 또는 [A], [C] 순서로 사용하지 않습니다. 추가 열 [C]가있는 인덱스를 사용하려면 술어를 [A], [B] 및 [C]로 정렬하여 인덱스를 적용해야합니다.


2
정확히 무엇을 달성 B=B합니까? 나는 당신이 아무 것도 얻지 못한다고 생각합니다. 어떤 옵티 마이저에 의해서도 무시되지 않는 증거는 없습니다.
Jack Douglas

2
B=B와 같지만 실제로는 B IS NOT NULL불필요합니다. 에 인덱스를 사용할 필요는 없습니다 (a,b).
Erwin Brandstetter
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.