쿼리 성능 가이드라인

이 문서에서는 SQL 쿼리를 최적화할 때 따라야 할 다양한 가이드라인을 설명합니다.

SQL 쿼리를 최적화할 때 주의해야 할 두 가지 차원이 있습니다:

  1. 쿼리 실행 시간. 이는 사용자가 GitLab을 경험하는 방식을 반영하기 때문에 매우 중요합니다.

  2. 쿼리 계획. 쿼리 계획을 최적화하는 것은 시간이 지남에 따라 쿼리가 독립적으로 확장될 수 있도록 하는 데 중요합니다. 인덱스가 쿼리가 성능을 유지하도록 돕는다는 사실을 인식하는 것은 이러한 계획을 분석하는 이유 중 하나입니다.

쿼리를 위한 타이밍 가이드라인

쿼리 유형 최대 쿼리 시간 비고
일반 쿼리 100ms 이는 강력한 제한은 아니지만, 쿼리가 이를 초과하는 경우, 최적화할 수 있는 이유를 이해하는 데 시간을 할애하는 것이 중요합니다.
마이그레이션 중 쿼리 100ms 이는 전체 마이그레이션 시간과 다릅니다.
마이그레이션 중 동시 작업 5min 동시 작업은 데이터베이스를 차단하지 않지만 GitLab 업데이트를 차단합니다. 여기에는 add_concurrent_indexadd_concurrent_foreign_key와 같은 작업이 포함됩니다.
마이그레이션 후 동시 작업 20min 동시 작업은 데이터베이스를 차단하지 않지만 GitLab 게시 업데이트 프로세스를 차단합니다. 여기에는 add_concurrent_indexadd_concurrent_foreign_key와 같은 작업이 포함됩니다. 인덱스 생성이 20분을 초과하는 경우, 비동기 인덱스 생성을 고려하세요.
백그라운드 마이그레이션 1s  
서비스 핑 1s 자세한 내용은 지표 계측 문서를 참조하십시오.
  • 쿼리 성능을 분석할 때, 보고 있는 시간이 차가운 또는 따뜻한 캐시에서 발생하는지 주의하세요. 이러한 가이드라인은 두 캐시 유형 모두에 적용됩니다.

  • 배치 쿼리로 작업할 때, 범위와 배치 크기를 변경하여 쿼리 시간 및 캐싱에 미치는 영향을 확인하세요.

  • 기존 쿼리의 성능이 좋지 않은 경우, 개선하기 위해 노력하세요. 너무 복잡하거나 개발이 지연될 경우, 후속 작업을 생성하여 시의적절하게 해결할 수 있도록 합니다. 데이터베이스 리뷰어 또는 유지 관리자의 도움과 지침을 언제든지 요청할 수 있습니다.

차가운 캐시와 따뜻한 캐시

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

쿼리를 처음 실행할 때 “차가운 캐시”에서 실행됩니다. 즉, 디스크에서 읽어야 합니다. 쿼리를 다시 실행하면 데이터는 캐시 또는 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 요청이 있을 가능성이 높다는 것입니다.

우리는 여전히 특정 필터링/정렬 조합이 특정 고객에 이익이 되는 팀에서 이를 추가할 수 있도록 허용하지만,

일부 사용자에게는 타임아웃될 것이라는 것을 받아들여야 합니다.