我正在使用GCP / App Engine构建供稿,该供稿以帖子分数的降序(修改后的时间戳)返回给定用户的帖子。不返回“已看到”的帖子将首先返回,其次是“已看到” = true的帖子。
用户创建帖子时,将为其每个关注者创建一个Feed实体(即,扇出收件箱模型)
如果许多用户同时加载其供稿,我当前的索引模型会导致“得分”索引出现爆炸式的索引和/或竞争吗?
index.yaml
indexes:
- kind: "Feed"
properties:
- name: "seen" // Boolean
- name: "uid" // The user this feed belongs to
- name: "score" // Int timestamp
direction: desc
// Other entity fields include: authorUid, postId, postType
通过以下方式获取用户的供稿:
SELECT postId FROM Feed WHERE uid = abc123 AND seen = false ORDER BY score DESC
我最好在'score'前面加上用户ID吗?这样会提高得分指数的效果吗?例如score =“ {字母数字用户ID}-{unix时间戳}”
您可以使用“分片查询”来提高性能,该分片式 固定长度的字符串到到期时间戳。索引已排序 在完整的字符串上,以便同一时间戳记的实体将是 位于索引的关键范围内。你跑多个 并行查询以获取每个分片的结果。
只有4个实体,我看到了44个索引,这似乎过多。
答案 0 :(得分:1)
您没有爆炸索引的问题,该问题特定于在复合索引中使用具有重复属性(即具有多个值的属性)的实体的查询。来自Index limits:
对于具有多个实体的情况,情况变得更糟 属性,每个属性都可以具有多个值。适应 这样的实体,索引必须包括所有可能的条目 属性值的 combination 。引用多个属性(每个属性具有多个值)的自定义索引可以“爆炸” 组合地,需要一个实体的大量条目 仅相对少量的可能的属性值。这样 由于大量索引, exploding indexes 可以显着增加Cloud Datastore中实体的存储大小 必须存储的条目。索引爆炸也很容易导致 该实体超过索引条目数或大小限制。
44个内置索引仅是为4个实体的多个索引属性创建的索引(可能您的实体模型具有约11个索引属性)。这是正常的。您可以通过清理模型使用并将所有您不打算在查询中使用的属性标记为未索引来减少数量。
但是,您确实存在在短时间内可能会有大量索引更新的问题-当具有许多关注者的用户创建时,所有这些索引都在狭窄范围内的帖子-热点,您所引用的文章适用于。在分数前添加关注者用户ID(而不是发布后的 creator ID),因为在相同索引范围内发生的更新次数相同,因此无济于事一个使用过帐事件(无论是否使用分片)都应有所帮助。追随者阅读帖子(当分数正确更新时)的影响较小,因为所有追随者不太可能完全同时阅读该帖子。
不幸的是,在关注者ID之前加起来对您打算执行的查询没有帮助,因为结果顺序将首先按照关注者ID而不是时间戳进行排序。
我会做什么:
seen
和score
属性的功能组合为一个:score
的值为0可以用来表示尚未看到帖子,任何其他值都可以表示看到的时间戳。索引更少,索引更新更少,存储空间更少。