降序__key__索引是否需要额外的写操作?

时间:2013-12-12 03:04:38

标签: google-app-engine

我一直在努力了解各种类型的索引如何影响每个实体所需的写操作数。我以为我已经弄明白了,但后来我发现了一个案例让我陷入了困境。

我有一个root用户实体,其中包含许多具有时间戳和一堆其他统计字段的GameSummary子实体(想想玩家名称,分数等)。

我的目标是能够为所有用户或特定用户查询GameSummaries列表。结果应该按时间戳按降序排序,我可能希望稍后添加一个搜索功能,在其他一些GameSummary字段上添加相等过滤器,并以相同的排序顺序返回结果。这一切都相当直接,但我显然希望用尽可能少的索引来做到这一点。

在timestamp属性上使用默认索引会创建两个索引(升序和降序),但我只需要其中一个索引,因此另一个写入只是开销。我的第一个想法是将属性设置为“noindex”(python中的Indexed = False),然后在index.yaml中添加我需要的降序索引。这最终无法正常工作,大概是因为查询规划器无论如何都试图使用默认索引而只返回没有结果。

然后我想到,如果我使用时间戳作为实体键,我可以按__key__排序(它没有默认索引),只添加我实际需要的索引。我正在使用--require_indexes运行dev服务器,这导致我的查询失败(按预期),直到我添加这两个索引:

- kind: GameSummary
  ancestor: no
  properties:
  - name: __key__
    direction: desc

- kind: GameSummary
  ancestor: yes
  properties:
  - name: __key__
    direction: desc

此时我查看了管理控制台中的数据存储区查看器,发现我的GameSummaries的Write Ops列只有2个(Entities和EntitiesByKind)。我期待在这里看到5的数量(第一个指数多1个,祖先指数多2个)。但是根据开发服务器的说法,似乎我得到了降序的__key__索引免费写入?

管理控制台对我说谎吗?或者我在__key__属性上遗漏了一些索引?

更奇怪的是,添加带有对__key__进行排序的其他属性的索引如下:

- kind: GameSummary
  ancestor: no
  properties:
  - name: Player
  - name: Enemy
  - name: __key__
    direction: desc

- kind: GameSummary
  ancestor: yes
  properties:
  - name: Player
  - name: Enemy
  - name: __key__
    direction: desc

也不会增加GameSummary实体的写操作数。我可能会在简单的情况下看到一些神奇的事情发生,但是这让它看起来越来越像开发服务器中的一个错误。

1 个答案:

答案 0 :(得分:1)

刚刚确认这是一个sdk错误,如果它不存在,你应该报告这个。我在实时服务器上用appstats测试了它,并且在添加降序索引时添加了额外的写入。

但是作为一个提示,因为我遇到了同样的事情,以避免多个索引并始终按降序排序,您可以对时间戳进行一点移位操作并存储其十六进制+随机数以避免冲突。它对我没有任何问题。虽然我的确切用法是我真的有自己的计数器而不是时间戳,但出于项目规范的原因。