쿼리 성능 가이드라인

이 문서는 SQL 쿼리를 최적화할 때 따를 여러 지침에 대해 설명합니다.

SQL 쿼리를 최적화할 때 주의해야 할 두 가지 측면이 있습니다.

  1. 쿼리 실행 시간입니다. 이는 사용자가 GitLab을 어떻게 경험하는지를 반영하기 때문에 매우 중요합니다.
  2. 쿼리 실행 계획입니다. 쿼리 실행 계획을 최적화하는 것은 시간이 흐름에 따라 쿼리가 독립적으로 확장될 수 있도록 하는 데 중요합니다. 테이블이 커지면서 쿼리의 성능을 유지하는 인덱스의 중요성을 분석하는 것이 좋은 예입니다.

쿼리에 대한 시간 가이드라인

쿼리 유형 최대 쿼리 시간 참고
일반 쿼리 100ms 이것은 강제적인 한계는 아니지만, 쿼리가 이 시간을 초과한다면 최적화할 수 있는 이유에 대해 시간을 들여 이해하는 것이 중요합니다.
마이그레이션 중의 쿼리 100ms 이것은 총 마이그레이션 시간과 다릅니다.
마이그레이션 중의 동시 작업 5분 동시 작업은 데이터베이스를 차단하지 않지만 GitLab 업데이트를 차단합니다. add_concurrent_indexadd_concurrent_foreign_key와 같은 작업이 이에 해당합니다.
마이그레이션 후의 동시 작업 20분 동시 작업은 데이터베이스를 차단하지 않지만 GitLab 업데이트 프로세스를 차단합니다. add_concurrent_indexadd_concurrent_foreign_key와 같은 작업이 이에 해당합니다. 인덱스 생성 시간이 20분을 초과하는 경우 비동기 인덱스 생성을 고려하십시오.
백그라운드 마이그레이션 1초  
서비스 핑 1초 자세한 내용은 Metrics Instrumentation 문서를 참조하십시오.
  • 쿼리 성능을 분석할 때 캐시의 차가운 상태 또는 따뜻한 상태에 있는 시간을 주목하세요. 이러한 가이드라인은 두 캐시 유형 모두에 적용됩니다.
  • 일괄 쿼리 작업을 수행할 때 범위 및 일괄 크기를 변경하여 쿼리 수행 및 캐싱에 미치는 영향을 확인하세요.
  • 기존 쿼리의 성능이 좋지 않다면 개선하는 데 노력을 기울이세요. 복잡하거나 개발을 지연시킬 수 있는 경우 해당 문제를 적시에 해결할 수 있도록 상세히 정리하세요. 데이터베이스 리뷰어나 유지보수자에게 도움과 지침을 요청할 수 있습니다.

차가운 캐시와 따뜻한 캐시

쿼리 성능을 평가할 때 차가운 캐시와 따뜻한 캐시의 차이를 이해하는 것이 중요합니다.

쿼리를 처음 실행하면 “차가운 캐시”에서 실행됩니다. 이는 디스크에서 읽어야 한다는 것을 의미합니다. 쿼리를 다시 실행하면 데이터를 캐시에서(또는 PostgreSQL이 공유 버퍼라고 하는 것) 읽을 수 있습니다. 이것이 “따뜻한 캐시” 쿼리입니다.

EXPLAIN 계획을 분석할 때 Buffers 출력을 살펴보면, EXPLAIN(analyze, buffers)로 실행하여 시간뿐만 아니라 차이점을 확인할 수 있습니다. Database Lab에서는 이러한 옵션을 자동으로 포함시킵니다.

따뜻한 캐시 쿼리를 실행할 경우 shared hits만 확인할 수 있습니다.

예를 들어, Database Lab을 사용하는 경우:

Shared buffers:
  - hits: 36467 (~284.90 MiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O

또는 psql의 설명 계획에서:

Buffers: shared hit=7323

캐시가 차가운 경우 reads도 볼 수 있습니다.

Database Lab을 사용하는 경우:

Shared buffers:
  - hits: 17204 (~134.40 MiB) from the buffer pool
  - reads: 15229 (~119.00 MiB) from the OS file cache, including disk I/O

psql에서:

Buffers: shared hit=7202 read=121

느린 목록 뷰 및 API

우리는 GitLab에서 종종 여러 다양한 필터 및 정렬 옵션이 필요한 필터링된 목록 뷰 및 API를 구축합니다. 이러한 옵션은 일반적으로 찾기 기능에 캡슐화되어 API/GraphQL 인수에 의해 노출됩니다. 많은 가능한 페이지네이션 성능 최적화가 있지만, 모든 정렬 및 필터링 조합을 성능이 우수한 상태로 만드는 방법이 항상 있지는 않습니다. 많은 옵션을 성능이 우수하도록 만들려고 시도할 경우 너무 많은 인덱스를 추가하게 되어 주 데이터베이스의 성능을 희생해야 할 수 있습니다. 이는 흔한 사용 사례에 대해서만 정당화되며 모든 필터 및 정렬 조합을 성능이 우수하도록 만들기 위한 방법으로 고려해서는 안 됩니다. 이는 실제로 특정 고객이 특정 필터링/정렬 조합으로 이점을 얻는 경우에만 정당화됩니다. 어떤 경우든 특정 사용자에게는 시간 초과되는 필터링 뷰 및 API 요청이 있을 것입니다. 특정 고객이 특정 필터링/정렬 조합으로 이점을 얻는 경우에만 추가할 수 있지만, 특정 사용자에게는 시간 초과되는 필터링 뷰 및 API 요청이 있을 것이며 이를 허용해야 합니다.