2009-07-19 1 views
2

난 그냥 EveryBlock의 소스 코드를 찾고 있었고, 난 경고/models.py 코드이 코드주의 :장고의 특성 캐시 - 요점은 무엇입니까?

def _get_user(self): 
    if not hasattr(self, '_user_cache'): 
     from ebpub.accounts.models import User 
     try: 
      self._user_cache = User.objects.get(id=self.user_id) 
     except User.DoesNotExist: 
      self._user_cache = None 
    return self._user_cache 
    user = property(_get_user) 

내가 무리의 주위에이 패턴을 발견했습니다,하지만 꽤 사용을 이해하지 못하는 . 전체 아이디어는 FK 자체 (자체 = 경고 개체)에 액세스 할 때 DB에서 한 번만 사용자 개체를 잡을 수 있는지 확인해야합니까? 왜 당신은 DB 캐싱 amd django의 ForeignKey() 필드에 의존하지 않았을까요? 모델 정의에는 외래 키 필드가 아닌 사용자 ID 만 포함된다는 사실을 알게되었습니다.

class EmailAlert(models.Model): 
    user_id = models.IntegerField() 
    ... 

통찰력을 주시면 감사하겠습니다.

답변

2

왜 이것이 IntegerField인지 알 수 없습니다. 그것은 분명히 ForeignKey (User) 필드 여야합니다 - 당신은 select_related()와 같은 것을 잃어 버렸습니다.

캐싱과 관련하여 많은 데이터베이스는 결과를 캐시하지 않습니다. 결과를 얻는 데 필요한 디스크에 데이터를 캐시하므로 결과를 찾는 데 두 번째로 빠릅니다. 우선, 그러나 그것은 여전히 ​​일을 할 것입니다.

데이터베이스 라운드 트립을 사용하여 검색합니다. 내 경험에 의하면 Django를 사용하면 항목 조회를 수행하는 데 로컬 Postgresql 서버에 대한 SQL 명령과 때때로 QuerySet의 중요한 오버 헤드가 0.5 ~ 1ms 정도 걸릴 수 있습니다. 당신이 필요하지 않다면 1ms가 많이 필요합니다 - 몇 번 해보면 30ms 요청을 35ms 요청으로 바꿀 수 있습니다.

SQL 서버가 로컬이 아니며 실제로 네트워크 왕복을 처리해야하는 경우 숫자가 커집니다.

마지막으로 사람들은 일반적으로 속성에 빠르게 액세스 할 것으로 기대합니다. SQL 쿼리를 발생시킬 정도로 복잡한 경우 일반적으로 결과 캐싱이 좋습니다.

2

데이터베이스는 내부적으로 캐시 작업을 수행하지만 관련 필드의 값을 확인하려고 할 때마다 db로 돌아가는 데 여전히 오버 헤드가 있습니다. 장고에서 쿼리를 설정하고 db에 연결하는 동안 네트워크 대기 시간을 데이터를 네트워크를 통해 반환하고 장고에서 개체를 인스턴스화하는 등의 작업을 수행합니다. 그 동안 데이터가 변경되지 않았 음을 알고 있다면 단일 웹 요청의 컨텍스트 내에서 처리 할 수 ​​있는지 상관하지 않을 것입니다. 매번 쿼리하는 것이 아니라 데이터를 한 번 가져 와서 캐시하는 것이 더 의미가 있습니다.

내가 작업하는 응용 프로그램 중 하나에는 엄청난 양의 데이터가 포함 된 매우 복잡한 홈 페이지가 있습니다. 이전에는 렌더링을 위해 400 개 이상의 db 쿼리를 수행했습니다. 지금은 리팩터링 했으므로 게시자의 것과 매우 유사한 기술을 사용하여 80 가지만 사용하므로 엄청난 성능 향상 효과가 있다고 생각하는 것이 좋습니다.