在Python Cloud Datastore上放置实体的速度一直很慢

时间:2018-02-12 15:43:52

标签: python python-3.x google-app-engine google-cloud-platform google-cloud-datastore

我在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字段上,该字段是对不同数据库中另一个对象的引用,用于跨数据库查找。

2 个答案:

答案 0 :(得分:2)

您可以使用Batch operations

提高多次连续写入(读取)的性能
  

批处理操作

     

Cloud Datastore支持允许的批量版操作   它可以在单个Cloud Datastore调用中对多个对象进行操作。

     

此类批量调用比为每个调用单独调用更快   个体实体,因为它们只产生一项服务的开销   呼叫。如果涉及多个实体组,则为所有人工作   组在服务器端并行执行。

client.put_multi([task1, task2])

答案 1 :(得分:2)

除了另一个答案中的批量推荐之外,还有其他一些做法会减少你的“投入”时间。

在数据存储上执行“写入”时,实际上是将数据多次写入多个表(索引)以提高性能。数据存储区通过牺牲一点写入时间效率和存储来优化查询时间性能。因此,例如,如果您索引三个普通字段,则每次写入基本上都会更新三个(已排序)表。通常情况下,不会被查询的字段not be indexed,这将节省您的时间和金钱。

由于“爆炸索引”效应,当您重复或嵌套字段时,“过度索引”的效果会更糟。基本上,您的数据在存储之前会被“展平”,因此具有多个重复字段会导致写入成本和时间的乘法增加。