我在Python 3灵活的应用引擎环境中通过Python库使用Google Cloud Datastore。我的烧瓶应用程序创建一个对象,然后将其添加到数据存储区:
ds = datastore.Client()
ds.put(entity)
在我的测试中,每次拨打put
都需要0.5-1.5秒才能完成。如果我像here一样一个接一个地拨打两个电话,这不会改变。
我想知道我的对象的复杂性是否是问题。它是多层次的,例如:
object = {
a: 1,
...,
b: [
{
d: 2,
...,
e: {
h: 3
}
}
],
c: [
{
f: 4,
...,
g: {
i: 5
}
}
]
}
我通过嵌套datastore.Entity
来创建,每个都用以下内容初始化:
entity = datastore.Entity(key=ds.key(KIND))
entity.update(object_dictionary)
两个列表都是3-4个项目。对象的JSON等价物是~2-3kb。
这不是推荐的做法吗?我应该做什么呢?
更多信息:
我目前没有在事务中包含put
的{{1}}。 put只是Entity
上的一个薄包装器。 put_multi似乎创建了put_multi
,发送了batch
,然后提交了Entity
。
我没有指定对象"名称/ ID" (数据存储在线控制台的标题)。我允许图书馆为我决定:
batch
其中datastore.key(KIND)
只是一个字符串,用于指定我的集合的名称。替代方案是:
KIND
我用它来更新对象,而不是我最初创建对象的地方。库生成的密钥随着时间的推移而增加,但不是单调的(例如:id = 4669294231158784,id = 4686973524508672)。
我不是100%肯定我正在做的事情的术语("实体是在同一个实体组中,或者如果你使用索引属性"),但人们似乎都在参考这个过程作为一个"嵌入式实体" (即here)。在数据存储区在线控制台中,在实体部分下,我只有一个" kind",而不是我的每个子对象的多种类型。这是回答你的问题,还是我能以某种方式找到它?
我在集合上只有一个索引,在一个单独的ID字段上,该字段是对不同数据库中另一个对象的引用,用于跨数据库查找。
答案 0 :(得分:2)
您可以使用Batch operations:
提高多次连续写入(读取)的性能批处理操作
Cloud Datastore支持允许的批量版操作 它可以在单个Cloud Datastore调用中对多个对象进行操作。
此类批量调用比为每个调用单独调用更快 个体实体,因为它们只产生一项服务的开销 呼叫。如果涉及多个实体组,则为所有人工作 组在服务器端并行执行。
client.put_multi([task1, task2])
答案 1 :(得分:2)
除了另一个答案中的批量推荐之外,还有其他一些做法会减少你的“投入”时间。
在数据存储上执行“写入”时,实际上是将数据多次写入多个表(索引)以提高性能。数据存储区通过牺牲一点写入时间效率和存储来优化查询时间性能。因此,例如,如果您索引三个普通字段,则每次写入基本上都会更新三个(已排序)表。通常情况下,不会被查询的字段not be indexed,这将节省您的时间和金钱。
由于“爆炸索引”效应,当您重复或嵌套字段时,“过度索引”的效果会更糟。基本上,您的数据在存储之前会被“展平”,因此具有多个重复字段会导致写入成本和时间的乘法增加。