在App Engine中查询Data Store的最有效方法

时间:2013-07-07 23:51:45

标签: java google-app-engine google-cloud-datastore

我有一个包含大约150,000个实体的数据存储。当我使用过滤器查询商店时,我的查询真的很慢。我的结构是完全平坦的,即每个实体都是彼此的兄弟。

1:使用GQL代替过滤器更好吗?

2:这不是Data Store的最佳用例,我应该使用SQL数据库吗?

以下是我的代码示例:

// Look for a buy opportunity
dateFilter = new FilterPredicate("date", FilterOperator.EQUAL, dt);
scoreFilter = new FilterPredicate("score", FilterOperator.LESS_THAN_OR_EQUAL, 10.0);
safetyFilter = new FilterPredicate("score", FilterOperator.GREATER_THAN_OR_EQUAL, -1.0);
mainFilter = CompositeFilterOperator.and(dateFilter,scoreFilter,safetyFilter);
q = new Query("StockEntity",stockKey).setFilter(mainFilter);
q.addSort("score", Query.SortDirection.ASCENDING);

stocks = datastore.prepare(q).asList(FetchOptions.Builder.withLimit(availableSlots));

更多细节:

  1. 150,000条记录,分为500个股票,每条股票约300条记录,日期范围内每天一条记录。

  2. 如上所述查询,其中传递了特定日期,并且根据“得分”有效过滤了500种股票,期望返回的记录数量在10到20之间,超过30在我的开发机器上完成几秒钟。

  3. 还没有尝试推动生产,但我想我会尝试下一步 - 我认为不会有太大的差异。我的开发机器是一个非常高规格的iMac。

2 个答案:

答案 0 :(得分:0)

https://developers.google.com/appengine/docs/java/datastore/queries#Java_Restrictions_on_queries

  

不等式过滤器最多只能限制一个属性

     

为了避免必须扫描整个索引表,查询机制   依赖于所有查询的潜在结果与一个查询相邻   另一个在索引中。为了满足此约束,可以使用单个查询   不使用不等式比较(LESS_THAN,LESS_THAN_OR_EQUAL,   GREATER_THAN,GREATER_THAN_OR_EQUAL,NOT_EQUAL)不止一个   所有过滤器的属性。例如,以下查询   是有效的,因为两个不等式过滤器都适用于同一属性:

简短的回答是你真的无法用数据存储做你想做的事。

答案 1 :(得分:0)

首先,该查询将在实际数据存储上运行得更快。

  1. 使用GQL或过滤器基本相同。

  2. 使用数据存储区时,首先应定义所需的功能。例如:您想要显示具有特定订单和过滤器的股票列表。现在查看您的应用所需的相同数据的任何其他视图。然后决定如何构建数据。

  3. 这与RDBMS非常不同,在RDBMS中,数据库通常可以容纳大多数功能而无需更改数据模型,并且数据建模在更通用的数据模型中。方式(规范化)。

    一般来说,如果您知道要读取的内容的KEY,那么数据存储区的读取性能将是最佳的,并且在执行查询时它将执行最差的操作,因为它总是需要索引'扫描&#39 ;.

    知道这一点,我倾向于经常使用祖先关系。请求“孩子们”#39;一个祖先似乎表现得更好,是一致的。例如,我使用如下查询:

    SELECT * WHERE ANCESTOR IS {key}
    

    其中{key}是祖先的关键(或者#39; parent')。此查询返回祖先实体以及在其路径中具有此祖先键的所有实体。在极少数情况下,我使用其中一个过滤器作为父级'值'分组对象但要小心,一旦写入实体,密钥就不可更改(您可以更改密钥,但会产生副本)。

    另外,如果您知道“套装”的平均尺寸。例如,属于订单的订单行。您可以选择在某处跟踪每个Orderline键。在批量读取中请求前20个键是快速操作。这基本上与索引相同,但是排序和过滤可以在写入时间'所以你的列表只包含与你的过滤器匹配的键。

    避免创建允许用户动态访问的视图。选择过滤器。

    如何进一步优化: 1.使用非规范化来最小化查找或查询的数量。 2.尽可能缓存(Memcache)。