0

我在上个月遇到了一个基本的数据存储查询问题。它涉及2个db.Models,其中一个使用db.ReferenceProperty引用另一个。数据存储性能,我的代码或数据存储延迟

问题是,根据管理日志的请求大约需要2-4秒才能完成。我将它分解为一个裸露的表单和一个列表来显示结果。 投入运行良好,但积累(在我看来)多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将Item模型中的所有Label键作为db.ListProperty存储。

我的测试数据只是Item中的10行和Label中的40。

所以我的问题:这是一个傻瓜差事来尝试优化这一点,因为高CPU使用率是由于数据存储的问题,或者我只是在代码中的某处搞砸了? ..fredrik

编辑:

我从djidjadji在谷歌的AppEngine邮件列表了很大的反响。

新的代码如下所示:

回答

3

有一定的事情可以做,以优化你的代码。例如,您正在迭代查询,这比获取查询并遍历结果效率低。

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

+0

我已经使用了Appstats。它是ReferenceProperty,它为每个循环制定和查询问题。但是我在googleappengine邮件列表上获得了很多帮助。我不知道如何在不引用ReferenceProperty的情况下做出相同的结果。解决方案是在for循环之前使用get_value_for_datastore。 – fredrik 2010-06-08 13:11:37

+1

你仍然得到了迭代查询的问题。调用.fetch()而不是迭代查询会更有效率。此外,请参阅此博客文章,了解解决参考属性的配方:http://blog.notdot.net/2010/01/ReferenceProperty-prefetching-in-App-Engine – 2010-06-08 15:09:18

0

不要只是尝试的东西。这是猜测。你只会在的时间。出于同样的原因,不要让其他人猜测。

每次都对。

只是暂停代码几次,看看调用堆栈。这会告诉你究竟是发生了什么事。

+0

不幸的是,当人们的知识未涵盖手头的问题。当人们不知道关于它的更多具体信息时,它变得更加困难,然后“它运行到许多查询”。我为Google Appengine邮件列表获得的解决方案是我不知道可以做的。我在文档中阅读过它,但不明白它做了什么。所以如果你说一个人不应该猜测,你会怎么做呢? – fredrik 2010-06-08 13:18:22

+0

@fredrik:这是我的建议。在pdb下运行你的程序(http://docs.python.org/library/pdb.html)。在运行时按Ctrl-Break或Ctrl-C。输入“w(here)”查看调用堆栈。了解它在做什么以及为什么。重复几次。如果X%时间花费在代码中,X%(+/-)堆栈将显示它。如果在数据存储中,同样的事情。测量将是近似的,但活动将是确定的和详细的。这就是我没有猜测的意思。 – 2010-06-08 14:44:29