2012-11-29 4 views
1

레일즈 애플리케이션의 어느 시점에서 캐시에서 많은 수의 ActiveRecord 객체를 검색합니다. 그러나 이러한 레코드 중 일부는 캐시에 저장 되었기 때문에 데이터베이스 자체에서 삭제 될 수 있으므로 레코드를 반복하고 각 레코드를 확인하여 레코드가 있는지 확인하십시오. 이것은 상당한 시간이 걸립니다. 이 작업을 수행하는보다 효율적인 방법이 있습니까?데이터베이스에서 많은 수의 레코드가 있는지 신속하게 확인할 수 있습니까?

+5

그건 [컴퓨터 과학에서 가장 힘든 두 가지] (http://martinfowler.com/bliki/TwoHardThings.html) –

+0

@ 대니 - 귀하의 의견은 무엇입니까? 나는 왜 누군가가 단순히 이것이 정말로 어렵다고 말하고 그것이 어떤 방식 으로든 원격으로 도움이된다고 생각하는 이유를 알지 못한다. 그걸 잊어 버리고 코드를 다시 디자인한다고 말하는거야? –

+0

@jimmcnamara - 의견을 보내 주셔서 감사합니다. 당신 말이 맞아요, 제 의견에는 분명히 명확하지 않았습니다. 내가 추가하고 싶은 것은 이것이 코딩에서 올바르게되기위한 더 힘든 일 중 하나이며, 유머 감각을 가지고 잘하면된다는 인식입니다. –

답변

2

데이터베이스에서 데이터를 삭제할 때 캐시에서 레코드를 삭제하지 않는 이유가 있습니까?

이러한 레코드를 캐시에 저장하고 db와 동기화해야하는 경우 db에서 레코드를 제거 할 때 캐시에서 해당 레코드를 제거해야하므로 비용이 많이 들지 않습니다. 나중에 중복 데이터를 확인해야하는 쿼리

1

이것은 DB 설계 문제로 간주 될 수 있으며 실제로 레일 문제는 아닙니다. 이러한 관점에서 테이블에 고유 인덱스가있는 AUTO INCREMENT 필드를 추가 할 수 있습니까?

활성 레코드 쿼리 인터페이스는 레코드 존재 확인을 수행 할 때에도 조회를 위해 궁극적으로 데이터베이스에 의존해야합니다. 따라서 db가 많은 작업을해야한다면 인터페이스가 얼마나 좋은지 상관없이 시간이 걸릴 것이며 레일 "잘못"이 아닙니다. db가 원하는 레코드의 유효성을 가능한 한 빨리 확인하십시오.

오라클에 익숙하다면 나중에 기존 레코드의 유효성을 검사 할 수 있도록 쿼리에 oracle rowid를 저장하는 것과 같은 생각입니다.

Danny가 말한 것처럼, 많은 양의 레코드를 캐싱하고 나중에 많이 사용하면 앱에 좋지 않은 생각 일 수 있습니다. 읽고 즉시 처리 할 수 ​​있습니까?

이 제안 중 어느 것도 빠른 수정 사항이 아닙니다.

0

확인하려는 레코드의 수가 너무 많으면 일괄 전송을 통해 하나씩 배송하는 비용을 상환해야 할 수 있습니다. 임시 테이블을 만들고 큰 테이블을 삽입하십시오 캐시에서 꺼낸 행 수를 계산 한 다음 임시 테이블을 원래 테이블과 조인합니다. 그러면 DBMS가 루핑을 수행합니다.

0

캐시의 결과에 관심있는 레코드의 기본 키가 포함되어 있으면 데이터베이스에서 키를 선택하고 되돌아 오는 것을 확인하여 결과를 쉽게 필터링 할 수 있습니다. 그런 다음 부실 기록을 걷어차 기 바랍니다.

results_from_cache = $redis.get("users") 

cached_user_ids = results_from_cache.map(&:id) 
actual_user_ids = User.where(id: user_ids).pluck(:id) 

results_minus_stale = results_from_cache.select do |user| 
    actual_user_ids.include?(user.id) 
end 
관련 문제