2016-07-15 3 views
0

쿼리 할 Postgres 데이터베이스에 1 천만 이상의 튜플이있는 테이블이 있습니다. "layer"정수, "time"및 "cnt"의 세 필드가 있습니다. 많은 레코드가 "레이어"에 대해 동일한 값을 공유합니다 (0에서 약 5로 분산되어 0-2 사이에 집중적으로 집중됨). "시간"은 상대적으로 고유 한 값을 가지지 만 쿼리 중에는 값이 조작되어 일부 값이 중복되고 그 값을 기준으로 그룹화됩니다. "cnt"는 계산에 사용됩니다.적절한 db 인덱스 선택

특정 시간 (WHERE 시간은 < = y 및 시간> = z) 사이의 특정 레이어 (WHERE 레이어 = x)에서 레코드를 쿼리하려고하며 내 GROUP BY 필드로 "시간"을 사용합니다. 나는 현재 (시간), (레이어), (시간, 레이어) 및 (레이어, 시간)에 각각 4 개의 인덱스가 있으며, 너무 많습니다 (상사가 제공 한 템플릿에서 이것을 복사했습니다).

온라인으로 읽은 것부터 상대적으로 고유 한 값을 가진 필드와 자주 검색되는 필드는 색인 생성에 적합한 후보입니다. 인덱스가 너무 많으면 쿼리 성능이 저하되는 것을 보았습니다. 따라서 쿼리를 삭제해야하는 이유가 있습니다.

이것은 (내가 다른 것을 사용하는 이유를 보지 못했기 때문에 btree가 좋다고 가정합니다.) 레이어에서 약간 더 자주 쿼리를 수행하기 때문에 최상의 인덱스 선택이 될 것입니다. 상대적으로 고유 한 값을 갖는 기준에 더 잘 부합합니다. 아니면 두 개의 색인, 즉 계층 1과 시간 1을 사용해야합니까?

또한 (시간, 계층)에 대한 색인이 (계층, 시간)과 다른가요? 그것이 내가 많은 지표를 갖게 한 혼란의 하나이기 때문입니다.

이 쿼리
WHERE layer = x and time <= y AND time >= z 

, 당신이 (layer, time)에 인덱스를 원하는 : 제공된 템플릿은

+0

'(레이어, 시간)'인덱스가있을 때'layer'는 중복됩니다. 하지만 '카디널리티'가 낮기 때문에 '레이어'자체는 어쨌든 사용되지 않을 것입니다. – zerkms

+0

당신의 경우에는'(레이어, 시간)'이 필요한 인덱스입니다. – zerkms

+0

"(시간, 레이어)에 대한 인덱스가 (레이어, 시간)과 다른가요?" --- 이름, 성, 이름이 같은 전화 번호부를 상상해보십시오. – zerkms

답변

2

귀하의 where 절은 것 같습니다 ... 단지 다른 순서로 배열의 같은 3 개 속성을 가진 여러 개의 인덱스를 가지고 있습니다. 인덱스에 cnt을 포함시켜 인덱스가 쿼리를 포함하도록 할 수 있습니다. 즉 모든 데이터 열이 인덱스에 있으므로 원래 데이터 페이지를 데이터에 액세스 할 필요가 없습니다 (정보를 잠 그려면 필요할 수 있습니다).

단일 열 인덱스가 필요하지 않으므로 원본 네 개의 인덱스가 중복됩니다. 네 가지를 모두 만드는 조언은 좋은 충고가 아닙니다. 그러나 (layer, time)(time, layer)은 다른 색인이며 경우에 따라 두 가지 색인을 모두 갖고있는 것이 좋습니다.

+0

나는 모든 질의가 레이어를 포함하기 때문에 실제로는 시간 (times)을 배제하려고 생각하고있다. 쿼리가 작동하는 방식은 먼저 특정 레이어 (WHERE 레이어 = x)로 이동 한 다음 해당 레이어 내에서 특정 범위 (시간 <= y 및 시간> = z) 내의 시간 값을 찾습니다. 시간이 레이어를 대체하는 경우는 결코 없으며, 쿼리는 항상 먼저 레이어를 필터링 한 다음 시간을 필터링합니다. 이 상황에서, (시간, 계층)이 (계층, 시간)에 비해 쓸모없는 것처럼 보입니까? – Ben

+0

@Ben'사이에있는 시간은 어디 까지나 ... GROUP BY 레이어 ' – zerkms

+0

아, 도움이되는 바로 가기 – Ben