【发布时间】: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