캐시된 쿼리 가이드라인
Rails SQL 쿼리 캐시의 동작 방식과 캐시된 쿼리가 N+1 문제를 마스킹하는 원인, 감지 및 개선 방법을 설명합니다.
Rails는 요청 기간 동안 데이터베이스 쿼리 결과를 캐시하는 데 사용되는 SQL 쿼리 캐시 를 제공합니다. Rails는 동일한 요청 내에서 동일한 쿼리를 다시 만나면, 데이터베이스에 쿼리를 재실행하는 대신 캐시된 결과 집합을 사용합니다. 쿼리 결과는 해당 단일 요청 기간 동안만 캐시되며, 여러 요청에 걸쳐 유지되지 않습니다. 캐시된 쿼리가 문제가 되는 이유 # 캐시된 쿼리는 데이터베이스 부하를 줄여주지만, 다음과 같은 비용이 여전히 발생합니다: 메모리를 소비합니다. Rails가 각 ActiveRecord 객체를 재인스턴스화해야 합니다. Rails가 객체의 각 관계(relation)를 재인스턴스화해야 합니다. 캐시된 쿼리 목록을 조회하는 추가 CPU 사이클이 필요합니다. 캐시된 쿼리는 데이터베이스 관점에서는 비용이 적지만, 메모리 관점에서는 더 비쌀 수 있습니다. 캐시된 쿼리는 N+1 쿼리 문제 를 마스킹할 수 있으므로, 일반 N+1 쿼리와 동일하게 취급해야 합니다. 캐시된 쿼리로 마스킹된 N+1 쿼리의 경우, 동일한 쿼리가 N번 실행됩니다. 데이터베이스를 N번 히트하지는 않지만 캐시된 결과를 N번 반환합니다. 매번 객체를 재초기화해야 하므로 CPU와 메모리 리소스에 더 큰 비용이 들어 여전히 비쌉니다. 대신 가능한 한 동일한 인메모리 객체를 사용해야 합니다. 새로운 기능을 도입할 때는 다음 사항을 따라야 합니다: N+1 쿼리를 피해야 합니다. 쿼리 수 를 최소화해야 합니다. 캐시된 쿼리 가 N+1 문제를 마스킹하지 않도록 특별히 주의해야 합니다. 캐시된 쿼리를 감지하는 방법 # Kibana를 사용한 잠재적 문제 감지 # GitLab.com은 실행된 캐시 쿼리 수를 pubsub-redis-inf-gprd* 인덱스의 db_cached_count 로 로그에 기록합니다. 실행된 캐시 쿼리 수가 많은 엔드포인트를 필터링할 수 있습니다. 예를 들어, db_cached_count 가 100을 초과하는 엔드포인트는 캐시된 쿼리로 마스킹된 N+1 문제를 나타낼 수 있습니다. 이 엔드포인트가 실제로 중복된 캐시 쿼리를 실행하고 있는지 추가로 조사해야 합니다. 캐시된 쿼리와 관련된 더 많은 Kibana 시각화를 위해 이슈 #259007, '잠재적 N+1 캐시 SQL 호출을 감지하는 데 도움이 되는 메트릭 제공' 을 읽어보세요. Performance Bar를 사용한 의심스러운 엔드포인트 검사 # 기능을 구축할 때 performance bar 를 사용하여 캐시된 쿼리를 포함한 데이터베이스 쿼리 목록을 확인하세요. performance bar는 실행된 총 쿼리 수와 캐시된 쿼리 수의 합이 100을 초과하면 경고를 표시합니다. 사용 가능한 통계에 대한 자세한 내용은 Performance bar 를 참조하세요. 확인해야 할 사항 # Kibana 를 사용하여 실행된 캐시 쿼리의 수가 많은 엔드포인트를 확인할 수 있습니다. db_cached_count 가 큰 엔드포인트는 중복된 캐시 쿼리가 많음을 의미할 수 있으며, 이는 종종 마스킹된 N+1 문제를 나타냅니다. 특정