Python 用于计数查询的Google云数据存储索引

Python 用于计数查询的Google云数据存储索引,python,google-cloud-datastore,app-engine-ndb,Python,Google Cloud Datastore,App Engine Ndb,谷歌云数据存储要求需要构建复合索引,以查询同一类型的多个字段。以下面的查询为例 class Greeting(ndb.Model): user = ndb.StringProperty() place = ndb.StringProperty() # Query 1 Greeting.query(Greeting.user == 'yash@gmail.com', Greeting.place == 'London').fetch() # Query 2 Greeting.qu

谷歌云数据存储要求需要构建复合索引,以查询同一类型的多个字段。以下面的查询为例

class Greeting(ndb.Model):
    user = ndb.StringProperty()
    place = ndb.StringProperty()

# Query 1
Greeting.query(Greeting.user == 'yash@gmail.com', Greeting.place == 'London').fetch()
# Query 2
Greeting.query(Greeting.user == 'yash@gmail.com', Greeting.place == 'London').count()
我正在使用python和ndb访问云数据存储。在上面的示例中,如果在
user
place
上未定义复合索引,则查询1将引发
NeedIndexError
。但是,即使
user
place
上没有索引,查询2也可以正常工作

我想了解云数据存储在强制使用索引获取实体列表(查询1)时,如何在没有索引的情况下获取计数(查询2)。我知道它存储每种索引的统计数据,这将导致对现有索引计数的更快响应(请参阅)。但我无法解释上述行为


注意:在查询给定类型的一个属性时没有问题,因为默认情况下,云数据存储在单个属性上有索引。

对于为什么会发生这种情况,没有明确而直接的解释,但很可能是因为改进的查询计划器如何处理
之字形索引

您可以在此处阅读更多关于此的信息:

count()
工作和
fetch()
背后的逻辑可能不是这样,因为使用
count()
时,不需要在内存中保存大量结果


因此,在
count()
的情况下,您可以通过将工作拆分为多个并行处理的块,然后将相应的计数相加为一个,从而轻松地进行扩展。使用游标/记录集无法廉价地实现这一点。

这是否意味着如果我在count query中的字段上显式添加索引,就不会提高性能?我只是想知道,如果没有索引,查询性能是否会下降。添加索引将提高您的读取性能,并且可能会降低运行查询的成本,尽管您需要运行测试来确认。虽然添加索引会增加您的写入和存储成本。在我发布问题后,我发现了一件有趣的事情。我在不同的字段组合上有3个索引。但是我没有运行count查询所依据的组合的索引。有趣的是,并非所有用于计数查询的字段组合都有效。其中一些在
需要索引器时失败。你对
zigzag
索引的猜测可能终究是正确的。考虑到这一点,您对读取性能的看法也是正确的。为了避免混淆,谷歌最好明确说明
zigzag
索引的用法。可能相关: