【问题标题】:Time of retrieving entities from datastore从数据存储中检索实体的时间
【发布时间】:2014-12-30 16:30:48
【问题描述】:

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

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

对 Datastore 执行查询的时间影响最大​​的是什么? 有什么方法可以加快我的查询速度?

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

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 是否重要?

感谢您的帮助。

【问题讨论】:

  • 您如何计算查询需要多长时间?进行数据存储调用的代码中是否存在开销?
  • 最好使用(String) result.getProperty("firstName")toString() 方法是“尽最大努力”将任何类型表示为字符串,而在这种情况下,您需要简单地转换类型。例如,如果您将错误的类型传递给“firstName”属性,如果您尝试强制转换它,您将得到一个异常(即您会发现有问题),但toString() 将工作,即使类型没有意义。

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


【解决方案1】:

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

您的查询时间表明您检索这些实体的方式存在问题。这可能是用于运行查询的代码中的问题,也可能是实体创建方式的问题。无法深入挖掘您在问题中提供的信息。

更新:

尝试改用这段代码,看看是否有改进:

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

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

【讨论】:

  • 只是在他的错误中指出另一种可能性:如果他没有为此查询的自定义索引并使用具有 7 个不同索引的 zigzag 算法,它肯定会减慢查询速度
  • 你完全正确。然而,Lukasz 在他的问题中确实提到了“复合索引”。此外,我们不知道他正在使用哪些运行时库和数据存储库。如果您创建的查询没有支持索引,其中一些会引发异常。
  • 我正在使用 Java Runtime Environment 和 DatastoreService 来运行我的查询。
  • 如何创建过滤器?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多