【问题标题】:Datastore performance, my code or the datastore latency数据存储性能、我的代码或数据存储延迟
【发布时间】:2010-07-22 05:18:48
【问题描述】:

上个月,我在一个非常基本的数据存储查询方面遇到了一些问题。它涉及 2 个 db.Model,其中一个通过 db.ReferenceProperty 引用另一个。

问题是根据管理员日志,请求大约需要 2-4 秒才能完成。我将其剥离为一个简单的表格和一个列表以显示结果。 put 工作正常,但 get 会累积(在我看来)很多 cpu 时间。

#The get look like this: 
outputData['items'] = {} 
labelsData = Label.all() 
for label in labelsData: 
        labelItem = label.item.name 
        if labelItem not in outputData['items']: 
                outputData['items'][labelItem] = { 'item' : labelItem, 'labels' : [] } 
        outputData['items'][labelItem]['labels'].append(label.text) 
path = os.path.join(os.path.dirname(__file__), 'index.html') 
self.response.out.write(template.render(path, outputData)) 
#And the models: 
class Item(db.Model): 
        name = db.StringProperty() 
class Label(db.Model): 
        text = db.StringProperty() 
        lang = db.StringProperty() 
        item = db.ReferenceProperty(Item) 

我尝试了多种不同的方式,即。而不是 ReferenceProperty 将项目模型中的所有标签键存储为 db.ListProperty。

我的测试数据在 Item 中只有 10 行,在 Label 中只有 40 行。

所以我的问题是:尝试优化它是愚蠢的差事,因为高 cpu 使用率是由于数据存储的问题还是我只是在代码中的某个地方搞砸了? ..弗雷德里克

编辑:

我在 google appengine 邮件列表中收到了 djidjadji 的好评。

新代码如下所示:

outputData['items'] = {}
labelsData = Label.all().fetch(1000)
labelItems = db.get([Label.item.get_value_for_datastore(label) for label in labelsData ])
for label,labelItem in zip(labelsData, labelItems):
   name = labelItem.name
   try:
       outputData['items'][name]['labels'].append(label.text)
   except KeyError:
       outputData['items'][name] = { 'item' : name, 'labels' : [label.text] }

【问题讨论】:

    标签: python google-app-engine optimization google-cloud-datastore


    【解决方案1】:

    您当然可以采取一些措施来优化您的代码。例如,您正在迭代一个查询,这比获取查询和迭代结果效率低。

    我建议使用Appstats 来分析您的应用,并查看Patterns of Doom 系列帖子。

    【讨论】:

    • 我用过 Appstats。正是 ReferenceProperty 为每个循环生成和查询是问题所在。但是我在 googleappengine 邮件列表中得到了一些很大的帮助。如果不参考 ReferenceProperty,我不知道如何得出相同的结果。解决方案是在 for 循环之前使用 get_value_for_datastore。
    • 您仍然遇到迭代查询问题。调用 .fetch() 而不是遍历查询会更有效率。另外,请参阅此博客文章以获取解决引用属性的方法:blog.notdot.net/2010/01/…
    【解决方案2】:

    不要只是尝试。那是猜测。你只会在一些的时候是对的。出于同样的原因,也不要让其他人猜测。

    每次都是正确的。

    只需将代码暂停几次,然后查看调用堆栈。这会准确地告诉你发生了什么。

    【讨论】:

    • 不幸的是,当一个人的知识不能涵盖手头的问题时,人们最终会猜测。当一个人不知道更多关于它的具体信息时,它变得更加困难,然后“它会运行许多查询”。我为 google appengine 邮件列表得到的解决方案是我不知道可以做到的。我在文档中读过它,但不明白它做了什么。所以如果你说不应该猜,你会怎么做?
    • @fredrik:这就是我的建议。在 pdb (docs.python.org/library/pdb.html) 下运行您的程序。在运行时按 Ctrl-Break 或 Ctrl-C。键入“w(here)”以查看调用堆栈。了解它在做什么以及为什么。重复几次。如果 X% 的时间花费在您的代码中,X% (+/-) 堆栈将显示它。如果在数据存储中,同样的事情。测量将是近似的,但活动将是确定和详细的。这就是我不猜测的意思。
    猜你喜欢
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 2020-12-12
    • 1970-01-01
    • 2013-01-03
    • 1970-01-01
    相关资源
    最近更新 更多