쿼리 성능 가이드라인
이 문서에서는 SQL 쿼리를 최적화할 때 따라야 할 다양한 가이드라인을 설명합니다.
SQL 쿼리를 최적화할 때 주의해야 할 두 가지 차원이 있습니다:
-
쿼리 실행 시간. 이는 사용자가 GitLab을 경험하는 방식을 반영하기 때문에 매우 중요합니다.
-
쿼리 계획. 쿼리 계획을 최적화하는 것은 시간이 지남에 따라 쿼리가 독립적으로 확장될 수 있도록 하는 데 중요합니다. 인덱스가 쿼리가 성능을 유지하도록 돕는다는 사실을 인식하는 것은 이러한 계획을 분석하는 이유 중 하나입니다.
쿼리를 위한 타이밍 가이드라인
쿼리 유형 | 최대 쿼리 시간 | 비고 |
---|---|---|
일반 쿼리 | 100ms |
이는 강력한 제한은 아니지만, 쿼리가 이를 초과하는 경우, 최적화할 수 있는 이유를 이해하는 데 시간을 할애하는 것이 중요합니다. |
마이그레이션 중 쿼리 | 100ms |
이는 전체 마이그레이션 시간과 다릅니다. |
마이그레이션 중 동시 작업 | 5min |
동시 작업은 데이터베이스를 차단하지 않지만 GitLab 업데이트를 차단합니다. 여기에는 add_concurrent_index 및 add_concurrent_foreign_key 와 같은 작업이 포함됩니다. |
마이그레이션 후 동시 작업 | 20min |
동시 작업은 데이터베이스를 차단하지 않지만 GitLab 게시 업데이트 프로세스를 차단합니다. 여기에는 add_concurrent_index 및 add_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 요청이 있을 가능성이 높다는 것입니다.
우리는 여전히 특정 필터링/정렬 조합이 특정 고객에 이익이 되는 팀에서 이를 추가할 수 있도록 허용하지만,
일부 사용자에게는 타임아웃될 것이라는 것을 받아들여야 합니다.