복붙노트

[RUBY-ON-RAILS] '존재'와 액티브 레코드 쿼리 협회 레일

RUBY-ON-RAILS

'존재'와 액티브 레코드 쿼리 협회 레일

나는 회원 (회원 응답 많은 관계로 하나가 있습니다) 조사를 수행 할 수있는 응용 프로그램에서 일하고 있습니다. 응답은 MEMBER_ID, question_id, 그들의 대답을 보유하고 있습니다.

설문 조사는 설문 조사를 완료하는 회원에 대한 응답 테이블의 모든 레코드가 그렇다면, 모두 또는 아무것도를 제출한다.

내 질문은, 어떻게 재 작성하기 때문에 실제로 작동하는 쿼리를 할 수 있습니까? (가) 키워드 EXISTS에 대한 SQL에서이 총리 후보가 될 것입니다.

 def surveys_completed
    members.where(responses: !nil ).count
 end 

해결법

  1. ==============================

    1.관련 응답 (들)이 같이 존재하는 경우는 시험 후 포함하고 사용할 수 있습니다 :

    관련 응답 (들)이 같이 존재하는 경우는 시험 후 포함하고 사용할 수 있습니다 :

    def surveys_completed
      members.includes(:responses).where('responses.id IS NOT NULL')
    end
    

    조인과 함께 여기에 대안이다 :

    def surveys_completed
      members.joins(:responses)
    end
    

    사용 용액은 4 레일 :

    def surveys_completed
      members.includes(:responses).where.not(responses: { id: nil })
    end
    

    유제:

  2. ==============================

    2.당신은 SQL 우아한에서 보석을 존재하는 방식으로 사용 레일 틱 키워드를 EXISTS 사용할 수 있습니다 :

    당신은 SQL 우아한에서 보석을 존재하는 방식으로 사용 레일 틱 키워드를 EXISTS 사용할 수 있습니다 :

    members.where_exists(:responses).count
    

    물론 당신은뿐만 아니라 원시 SQL을 사용할 수 있습니다 :

    members.where("EXISTS" \
      "(SELECT 1 FROM responses WHERE responses.member_id = members.id)").
      count
    
  3. ==============================

    3.또한 하위 쿼리를 사용할 수 있습니다 :

    또한 하위 쿼리를 사용할 수 있습니다 :

    members.where(id: Response.select(:member_id))
    

    뭔가 비교로는 (성능이 향상되는 당신이 그들을 필요하지 않은 경우) 관련 모델을로드 할 수 없습니다 포함되어 있습니다.

  4. ==============================

    4.당신은 레일 5에 당신이 left_joins를 사용해야 위의 경우. 그렇지 않으면 수동 것 또한 일을 "LEFT OUTER 조인". 이 https://stackoverflow.com/a/18234998/3788753에서 언급 포함 사용하는 것보다 더 성능이 좋은 것입니다. left_joins는 "LEFT OUTER 조인"쿼리를 작성하는 반면, 메모리에 관련 개체를로드하려고 시도합니다 포함되어 있습니다.

    당신은 레일 5에 당신이 left_joins를 사용해야 위의 경우. 그렇지 않으면 수동 것 또한 일을 "LEFT OUTER 조인". 이 https://stackoverflow.com/a/18234998/3788753에서 언급 포함 사용하는 것보다 더 성능이 좋은 것입니다. left_joins는 "LEFT OUTER 조인"쿼리를 작성하는 반면, 메모리에 관련 개체를로드하려고 시도합니다 포함되어 있습니다.

    def surveys_completed
      members.left_joins(:responses).where.not(responses: { id: nil })
    end
    

    아무 관련 기록이없는 경우에도 (당신이 전무에 의해 발견되는 경우 위의 쿼리 등)이 포함되어 여전히 더 많은 메모리를 사용합니다. 내 테스트에서 나는 레일 5.2.1에 사용 ~ 33 배 더 많은 메모리를 포함 발견했다. 레일 4.2.x를에 그것은 수동으로 조인하고 비교 ~ 44x 더 많은 메모리이었다.

    시험이 요점을 참조하십시오 : https://gist.github.com/johnathanludwig/96fc33fc135ee558e0f09fb23a8cf3f1

  5. from https://stackoverflow.com/questions/18234602/rails-active-record-querying-association-with-exists by cc-by-sa and MIT license