InfoGrab DocsInfoGrab Docs

QueryRecorder

테스트에서 N+1 쿼리 문제를 감지하고 방지하기 위한 QueryRecorder 도구의 사용법과 권장 패턴을 설명합니다.

QueryRecorder는 테스트에서 N+1 쿼리 문제 를 감지하기 위한 도구입니다. spec/support/query_recorder.rb 에 9c623e3e 를 통해 구현되어 있습니다. 원칙적으로, 머지 리퀘스트는 쿼리 수를 증가시켜서는 안 됩니다 . N+1 쿼리를 방지하기 위해 .includes(:author, :assignee) 같은 코드를 추가하게 된다면, QueryRecorder를 사용해 테스트로 이를 강제하는 것을 고려하세요. 이를 적용하지 않으면, 추가 모델에 접근하는 새로운 기능이 해당 문제를 조용히 재발시킬 수 있습니다. QueryRecorder의 동작 방식 # 이 방식의 테스트는 ActiveRecord가 실행하는 SQL 쿼리 수를 세는 방식으로 동작합니다. 먼저 제어 카운트(control count)를 측정한 다음, 데이터베이스에 새 레코드를 추가하고 다시 카운트를 실행합니다. 쿼리 수가 크게 증가했다면 N+1 쿼리 문제가 존재하는 것입니다. 예를 들어, 카운트 사이에 이슈를 5개 생성할 경우, N+1 문제가 있다면 쿼리 수가 5만큼 증가합니다. it "avoids N+1 database queries", :request_store, :use_sql_query_cache do visit_some_page # warm-up control = ActiveRecord::QueryRecorder.new(skip_cached: false) { visit_some_page } create_list(:issue, 5) expect { visit_some_page }.to issue_same_number_of_queries_as(control) end 기댓값과 제어값 모두 QueryRecorder 인스턴스로 사용할 수도 있습니다: it "avoids N+1 database queries", :request_store, :use_sql_query_cache do visit_some_page # warm-up control = ActiveRecord::QueryRecorder.new(skip_cached: false) { visit_some_page } create_list(:issue, 5) action = ActiveRecord::QueryRecorder.new(skip_cached: false) { visit_some_page } expect(action).to issue_same_number_of_queries_as(control) end 경우에 따라 무관한 이유로 실행 간 쿼리 수가 약간 달라질 수 있습니다. 이런 경우 issue_same_number_of_queries_as(control).with_threshold(acceptable_change) 를 사용해야 할 수 있지만, 가능하면 피하는 것이 좋습니다. 이 테스트가 실패하고 제어값이 QueryRecorder 로 전달된 경우, 실패 메시지는 가장 긴 공통 접두사를 기준으로 쿼리를 매칭하고 유사한 쿼리를 그룹화하여 추가 쿼리가 어디에 있는지 알려줍니다. 권장 패턴 # N+