如何排序优化的密钥查询

时间:2014-06-18 10:25:49

标签: sorting google-cloud-datastore

我使用数据存储本地api访问gae数据库(出于充分研究的具体原因)。我想优化代码并在我的请求中使用memcache而不是直接获取值,问题是我的查询是否已排序。

当我在查询中执行findProductsByFiltersQuery.setKeysOnly();时,收到此错误:

  

提供的仅限密钥的多查询需要执行一些排序   记忆。因此,此查询只能按键排序   属性,因为这是内存中唯一可用的属性。

疲惫的事情是它从请求的某个复杂性开始发生,例如此请求失败:

SELECT __key__ FROM Product WHERE dynaValue = _Rs:2 AND productState = PUBLISHED AND dynaValue = _RC:2 AND dynaValue = RF:1 AND dynaValue = ct:1030003 AND dynaValue = _RS:4 AND dynaValue = _px:2 AND itemType = NEWS ORDER BY modificationDate DESC

虽然这个过去了:

SELECT __key__ FROM Product WHERE itemType = CI AND productState = PUBLISHED ORDER BY modificationDate DESC

有人可以解释一下为什么会发生这种情况,并且如果在获取密钥时无法进行排序,那该功能是什么? :由于结果是分页的,因此从第一个过滤请求中获取一组错误的密钥是没用的。那是怎么想的呢?

另请注意,当我执行非keysOnly非常长的请求时,我会收到此消息

  

拆分提供的查询需要太多的子查询   合并在记忆中。

at com.google.appengine.repackaged.com.google.common.base.Preconditions.checkArgument(Preconditions.java:129)
at com.google.appengine.api.datastore.QuerySplitHelper.splitQuery(QuerySplitHelper.java:99)
at com.google.appengine.api.datastore.QuerySplitHelper.splitQuery(QuerySplitHelper.java:71)

有人可以解释一下,当索引值时,内存处理有可能吗?或者只是devmode服务器才会出现此错误?

1 个答案:

答案 0 :(得分:1)

在数据存储区中使用ORIN!=运算符时,必须进行内存中查询。作为described in this blog post,使用这些运算符的查询在客户端中分成多个数据存储区查询。例如:

SELECT * FROM Foo WHERE A = 1 OR A = 2

分为两个查询:

SELECT * FROM Foo WHERE A = 1
SELECT * FROM Foo WHERE A = 2

如果您在查询中添加ORDER BY B,则两个子查询都会获得此订单:

SELECT * FROM Foo WHERE A = 1 ORDER BY B
SELECT * FROM Foo WHERE A = 2 ORDER BY B

虽然这些数据存储区查询中的每一个都返回按B排序的结果,但查询的并集却不是。在客户端,SDK合并了由B排序的两个结果。

为了做到这一点,数据存储区查询必须实际返回ordered属性,否则SDK不知道将这些属性合并在一起的正确方法。

如果您要编写包含大量过滤条件的查询,请务必仅使用AND过滤条件。这将允许所有操作仅在数据存储区中执行,在这种情况下,不需要内存中的排序。