2010-08-03 5 views
0

저는 Google App Engine으로 작업 해 왔으며 일부 데이터 쿼리에서 성능이 약간 저하되고 있습니다. App Engine 데이터 스토어 디자인은 SQL 데이터베이스 작업과는 다른 사고 방식이며 최선의 방법이라고 확신하지 못한다고 읽었습니다. 특히GQL 쿼리 최적화 및 테이블 아키텍처

:

가 나는 Foo 유형과 UserFoo 유형이 나는 바른 길에 들어 가려고하는 두 가지 질문이 있습니다. 각 UserFoo은 해당 Foo의 "인스턴스"이며 해당 인스턴스에 특정한 데이터를 보유합니다. 내 Foo 유형은 고유 식별자 인 fooCode 속성을 가지고 있으며 속성을 사용하여 각 UserFoo을 각 Foo으로 매핑합니다. 나는 다음과 같이 코드를 각 푸에 운항합니다 :

foos = Foo.all().filter('bar =', bar) 
for foo in foos: 
    userFoo = UserFoo.all().filter('userKey =', user).filter('fooCode =', foo.fooCode) 

참고 : 우리가 쉽게 삭제하고 새 Foo들 다시 추가 한 다음 모든 다시 매핑 할 필요가 없습니다 수 있도록 내가 참조 키를 통해 fooCode를 사용하고 있습니다 해당 UserFoo s. 일반에서

:

을 사용하는 GAE 데이터 저장소 테이블과 모범 사례를 설계하는 일반적인 방법은 무엇입니까? 일반에서

+0

Foo와 UserFoo 객체간에 1 대 1 대응이 있습니까? –

+0

당신이 보여주는 것은 사실 GQL 쿼리가 아니라는 점에 유의하십시오. –

+0

1 많은 UserFoo를 푸십시오. 또한 GqlQuery를 원래는 호출했지만 느리게 읽었 기 때문에 변경했습니다. –

답변

1

이것은 패턴이 staircase of gets입니다. 해결책은 ReferenceProperty pre-fetching입니다.

ReferenceProperty를 사용하지 않기로 결정했습니다. 이 선택의 재검토를 권합니다.

참고 : 우리가 쉽게 삭제하고 새로운 FOOS 다시 추가하지 다음에있는 모든 해당 UserFoos를 매핑 할 수 있도록 내가 참조 키를 통해 fooCode를 사용하고 있습니다.

엔터티 키는 경로의 인코딩 된 표현 인 엔티티 및 해당 조상의 종류와 이름 또는 ID입니다.Foo을 삭제했다가 다시 만든 경우 이름이나 ID가 다른 경우에만 다른 키가 있습니다. 구형 엔티티와 새로운 엔티티에 동일한 fooCode을 부여하는 방법이 있다면 fooCode을 키 이름으로 쉽게 사용할 수 있습니다. 이렇게하면 삭제 된 후 다시 원래 키가 유지되도록 Foo이 추가됩니다.

+0

이러한 링크를 읽는 것이 좋습니다. 지금 데이터 저장소를 재구성하고 있습니다. 이것을 지적한 모든 사람들에게 감사드립니다! –

1

: 가능한 한만큼

  • 비정규. 가능한 경우 언제든지 키를 통해 엔터티를 참조하십시오.

  • 데이터 저장소에서 데이터를 가져 오는 가장 빠른 방법은 입니다.

특히, 참조 속성을 사용하여 필터로 들어가는 코드가 아닌 관계를 설정하면 성능이 크게 향상 될 수 있습니다. UserFoo의 Foo를 쿼리하면 Foo를 제거하고 다시 매핑하는 것보다 더 자주 좋은 일이 일어난다는 것을 추측 할 것입니다. 이 경우 실용적이고 데이터 저장소에서해야 할 일은 참조 속성을 사용하는 것입니다.

또한 Foo-UserFoo 관계를 단일 엔티티로 비정규화할 수 있으면 전체 일련의 쿼리가 필요하지 않습니다.

1

나는 다음과 같이 변경 제안 :

  1. 는 푸를 참조 UserFoo에 ReferenceProperty를 사용하거나 필요한 경우 그것을 자식 개체를 확인합니다. 기존 엔티티를 다시 매핑하는 것에 대한 귀하의 의견을 이해하지 못합니다.
  2. 각 UserFoo에 'bar'속성 복사본 추가
  3. UserFoo.all(). filter ('bar =', bar) .order ('userKey')에 대해 단일 쿼리를 수행하십시오. 결과는 막대로 필터링되고 사용자별로 그룹화되며 사용자 당 하나가 아닌 단일 쿼리 만 필요합니다.
  4. .fetch()를 반복 실행하지 않고 쿼리에서 호출하여 결과를 한 번에 가져옵니다. 이것은 훨씬 더 효율적입니다.
  5. ReferenceProperty prefetching을 사용하면 필요한 경우 각 UserFoo의 Foo 객체를 검색 할 수 있습니다.