2017-11-16 15 views
0

내 모델에 다음과 같은 방법이 있다고 가정 해 봅시다.memoization은 활성 레코드 관계에서 작동합니까?

def all_users 
    @users ||= User.all 
end 

와 나는 내가 여러 다른 ID에 대한 all_users.where(id: 123)을하고있는 중이 야 내 모델에서 다른 방법이있다. 매번 db에 대해 쿼리/적중을 실행하거나 캐시 된 결과 집합에서 레코드를 직접 가져옵니다.

+0

[xy 문제] (https://meta.stackexchange.com/a/66378/284887)처럼 들립니다. 왜 이러한 쿼리를 암기하고 수정하려고하는 실제 문제에 대해 자세히 설명하고 싶은지 설명해주십시오. – spickermann

답변

2

SQL 캐싱에 대해서는 docs을 참조하십시오. 쿼리가 정확히 일치하면 캐시에서 결과를 가져옵니다. 다른 ID에 대한 요청은 개별 쿼리로 이어집니다.

#all을 사용할 때는주의해야합니다. 그러나 모든 레코드를 메모리에로드하므로주의하십시오. 이것은 느리고 많은 메모리를 소비 할 수 있습니다. 장기적으로 개별 User.find(X) 검색어를 사용하는 것이 좋습니다.

+0

그래서 나는 10 개의 id 목록을 가지고 있으며 id를 통해 반복하고'all_users.where (id : #id)'를 실행하면 10 개의 quries가 실행됩니까? –

1

User.all은 활성 레코드 관계를 반환합니다.이 레코드를 사용하여 무언가를 시도하고 시도 할 때까지는 데이터를 가져 오지 않습니다 (예 : 배열과 유사한 메소드 호출). 레일스는 릴레이션에 대한 데이터를로드합니다 (아직로드되지 않은 경우). 당신이

all_users.sample(5) 
all_users.detect {|record| ... } 

등의 작업을 수행 할 경우

그럼 한 번만 데이터베이스에서 가져올 수 있습니다.

그러나 where, joins 등의 방법을 사용하면 ... 새 관계를 반환하면 해당 관계는 데이터가 필요할 경우 데이터베이스에 도달해야합니다.

all_users.where(id: 1).first 
all_users.where(id: 2).first 
all_users.where(id: 3).first 

예를 들어 3 개의 쿼리를 실행합니다.

ID 목록이있는 경우 누락 된 값을 허용하려면 User.find(ids) (또는 User.where(id: ids))을 수행하는 것이 훨씬 더 좋습니다.