代码之家  ›  专栏  ›  技术社区  ›  Nick Gotch

GQL查询优化与表结构

  •  0
  • Nick Gotch  · 技术社区  · 14 年前

    我一直在使用googleappengine,我的一些数据查询的性能有些慢。我读到过,设计appengine数据存储与使用SQL数据库是一种不同的思维方式,我不确定我是否用最好的方式来实现这一点。我有两个问题要问:

    明确地:

    我有一个 Foo 类型和a UserFoo 类型。每个 用户foo 是对应的 并保存特定于该实例的数据。我的 fooCode 属性,它是唯一的标识符,我将每个 用户foo 属性。然后我对每个Foo进行如下操作:

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

    注意:我正在使用 食品代码 一个参考键,以便我们可以轻松地删除和重新添加新的 用户foo s。

    一般来说:

    设计GAE数据存储表的典型方法和使用它们的最佳实践是什么?

    3 回复  |  直到 14 年前
        1
  •  1
  •   Drew Sears    14 年前

    这就是 staircase of gets ReferenceProperty pre-fetching .

    问题是您决定不使用ReferenceProperty。我建议你重新考虑这个选择。

    参考键,以便我们 然后必须重新映射所有

    请记住,实体键只是其路径的编码表示:实体及其任何祖先的种类、名称或ID。如果您删除然后重新创建 Foo fooCode ,您可以轻松地使用 食品代码 作为键名,这将允许删除然后重新添加 保留其原始密钥。

        2
  •  1
  •   Adam Crossland    14 年前

    • 尽可能地去规范化。

    • 通过其密钥引用实体 尽可能;它是最快的 从数据存储中获取数据的方法。

    另外,如果Foo-UserFoo关系可以被反规范化为单个实体,那么就不需要全部查询。

        3
  •  1
  •   Nick Johnson    14 年前

    我建议做以下修改:

    1. 使用UserFoo中的ReferenceProperty引用其Foo,或者使其成为子实体(如果合适)。我不理解你关于重新映射现有实体的评论-那应该是没有必要的。
    2. 将“bar”属性的副本添加到每个UserFoo
    3. 对UserFoo.all().filter('bar=',bar).order('userKey')执行单个查询。结果将按栏过滤并按用户分组,并且只需要一个查询,而不是每个用户一个查询。
    4. 使用 ReferenceProperty prefetching