【发布时间】:2022-02-04 16:17:35
【问题描述】:
我有一个使用 go115 运行时的 App Engine 应用,它通过 google.golang.org/appengine/v2/datastore 包与 Cloud Datastore 交互。该应用使用自动分配的整数 ID 和 Rating 字段(以及其他字段)插入和查询 Song 实体:
type Song struct {
// ...
Rating float64 `json:"rating"`
// ...
}
对于 19,900 个 Song 实体,https://console.cloud.google.com/datastore/stats 报告的数据大小为 15.53 MB,内置索引大小为 102.27 MB,复合索引大小为 86.31 MB。该应用在us-central 中运行,而Datastore 在nam5 (us-central) 中。
从 App Engine 运行时,以下仅键查询始终需要 2-4 秒才能返回 13,571 个键:
q := datastore.NewQuery("Song").KeysOnly().Filter("Rating >=", 0.75)
keys, err := q.GetAll(ctx, nil)
使用Run 而不是GetAll 并在迭代时收集ID 似乎要快一点。我还尝试使用笔记本电脑上的cloud.google.com/go/datastore 包,以确保旧的appengine 包不是特别慢,但结果要差得多(7-9 秒)。
我的理解(基于 Indexes document 和 the I/O 2010 "Next gen queries" talk 之类的内容)是 Datastore 会自动维护 Rating 字段的索引。我希望使用该索引来满足这个查询是微不足道的。结果集中的整数 ID 似乎应该消耗大约 100 KB 的空间。
我还没有从 Google 那里找到任何关于从 Datastore 获得何种性能类型的官方指导,但这比我希望的要慢得多。当我通过对数据的 JSON 转储运行 jq 工具和 grep 在笔记本电脑上执行此查询的蛮力逼近时,只需要 400 毫秒。
是否预计只有键的普通数据存储区查询需要几秒钟才能返回数千个键?
当我运行返回较小结果集的仅键查询时,性能会更好:返回 300-400 个键的查询通常需要 100-200 毫秒,而返回少于 200 个键的查询在 40-70 毫秒内完成。
我无法修改我的许多查询来限制它们返回的结果数量:
-
我有时会并行执行多个查询,然后手动将它们的结果相交或相减以绕过 inequality filters are limited to at most one property 的数据存储限制。
-
我有时会获取完整的结果集,以便返回其中的一个随机子集。我已经阅读了有关 approaches people take to simulate randomized results when using Datastore 的信息,但我认为它们不会在这里工作,因为我的查询已经使用了不等式过滤器。
我可以想到在某些情况下可能会有所帮助的技巧(例如,对我的实体进行分片/分区,以便我可以并行运行多个查询),但我希望尽可能避免这种情况。
【问题讨论】:
标签: google-app-engine google-cloud-platform google-cloud-datastore