2014-11-03 64 views
0

我有一个使用数据存储的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类来记录诊断信息。我可以在管理控制台中看到两个日志之间的时差。 当我把日志放入迭代实体的循环的第一行和最后一行时,我可以在迭代之间看到奇怪的暂停。我不知道是什么原因。

实施例:
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个过滤器,并建立新的COM posite指数。它似乎更快,但它在检索大约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在一根绳子上的财产?

感谢您的帮助。

+0

你如何计时查询需要多长时间?也许在使数据存储调用的代码中有开销? – bighonestjohn 2014-11-04 10:04:59

+0

最好使用'(String)result.getProperty(“firstName”)'。 'toString()'方法是将所有类型表示为String的“尽力而为”方法,而在这种情况下,您只需简单地转换类型。例如,如果你将错误的类型传递给“firstName”属性,那么如果你尝试转换它,你会得到一个异常(即你会发现有问题),但是'toString()'即使在这种类型没有意义。 – 2014-11-04 16:26:40

回答

1

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

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

UPDATE:

尝试使用此代码代替,看看你看到的改进:

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

你应该在你预料有超过10个结果中查询每次使用这条线。请注意,该数字可以是0到1000之间的任意值,因此您可以针对不同的查询尝试不同的限制,以查看最佳效果。

+0

只是指出他的错误的另一种可能性:如果他没有这个查询的自定义索引,并使用7个不同索引的锯齿算法,它肯定会减慢查询 – Patrice 2014-11-03 22:44:03

+0

你是完全正确的。然而,Lukasz在他的问题中确实提到了“综合指数”。另外,我们不知道他正在使用哪个运行时和数据存储库。如果您创建一个没有支持索引的查询,其中一些会引发异常。 – 2014-11-04 04:56:39

+0

我正在使用Java运行时环境和DatastoreService来运行我的查询。 – lukasz 2014-11-04 08:28:16