从数据存储区检索实体的时间

时间:2014-11-03 22:01:26

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

我有一个使用数据存储区的App Engine应用程序。数据存储中的一种包含 超过2,000,000个实体。那种查询非常慢 例如,返回约50个实体的查询需要3-5秒。我不知道过滤器的数量是否重要但在这种情况下我在查询时设置了7个过滤器 其他类型的查询在我看来也很慢。例如查询返回大约20 包含超过90 000个实体的实体大约需要1秒钟。

我为这些查询构建了复合索引,但它没有太多帮助。改变块 大小和仅使用键查询也无济于事。

对数据存储执行查询的时间影响最大​​? 有没有办法加快我的查询?

我检索实体的方式类似于我在文档中找到的示例:

Query q = new Query("Person").setFilter(heightRangeFilter);

    PreparedQuery pq = datastore.prepare(q);

    for (Entity result : pq.asIterable()) {

      String firstName = result.getProperty("firstName").toString();
      String lastName = result.getProperty("lastName").toString();
      Long height = (Long) result.getProperty("height");

    }

该实体的总大小为423.33 MB,内置索引:2.87GB,复合索引:1.85GB

我正在使用Logger类来记录诊断信息。我可以在管理控制台中看到两个日志之间的时差。 当我将log登录到遍历实体的循环的第一行和最后一行时,我可以看到迭代之间的奇怪暂停。我不知道是什么原因。

例:
   15:06:30.565开始
   15:06:30.566停止
   15:06:30.566开始
   15:06:30.566停止
   15:06:30.572开始
   15:06:30.572停止
   15:06:30.583开始
   15:06:30.583停止
   15:06:30.595开始
   15:06:30.595停止
   15:06:30.595开始
   15:06:30.595停止
   15:06:30.595开始
   15:06:30.596停止
   15:06:30.658开始
   15:06:30.658停止
   15:06:30.659开始
   15:06:30.659停止
   15:06:30.666开始
   15:06:30.666停止
   ...

编辑: 我修改了我的查询以使用6个过滤器并为它构建新的复合索引。它似乎更快,但在检索大约100个实体时仍然运行超过2秒。 我创建过滤器的方式类似于文档中的示例:

Filter timeMinFilter =
  new FilterPredicate("time",
                      FilterOperator.GREATER_THAN_OR_EQUAL,
                      startTime);

Filter timeMaxFilter =
  new FilterPredicate("time",
                      FilterOperator.LESS_THAN_OR_EQUAL,
                      stopTime);

Filter heightRangeFilter = CompositeFilterOperator.and(timeMinFilter, timeMaxFilter);

我在字符串属性上设置FilterOperator.GREATER_THAN_OR_EQUAL和FilterOperator.LESS_THAN是否重要?

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

App Engine上的查询速度不依赖于数据存储区中存储的实体数量。它仅取决于您从查询中检索的实体的数量和大小。

您查询的时间表明您检索这些实体的方式存在问题。它可能是用于运行查询的代码中的问题,或者它可能是实体创建方式的问题。没有办法深入了解您在问题中提供的信息。

更新:

尝试使用此代码,看看是否有改进:

for (Entity result : pq.asList(FetchOptions.Builder.withDefaults().chunkSize(100).prefetchSize(100)) { 

每次在查询中预期超过10个结果时,都应该使用此行。请注意,该数字可以介于0到1000之间,因此您可以针对不同的查询尝试不同的限制,以查看最佳效果。