如何减少对数据存储的请求数量 [英] How to reduce number of requests to the Datastore

查看:111
本文介绍了如何减少对数据存储的请求数量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据AppStats,当使用200个文档和1个DocUser运行下面的脚本时,大约需要5000ms。总结在于,对于lastEditedBy(datastore_v3.Get)的每个锁定都有一个对数据存储的请求,每个锁定需要6-51ms。



我在做的是使某些东西能够显示具有多个属性的许多实体,其中一些属性来自其他实体。永远不会有大量的实体(< 5000),因为这更像是一个管理界面,所以永远不会有很多并发用户。



我试过通过缓存DocUser实体来进行优化,但是我无法从上面的查询中获取DocUser键,而不向数据存储区发出新请求。



1)这是否有意义 - 是我正在经历的延迟?

<2>有没有办法让这个工作没有额外的请求到数据存储?



models.py

  class Document(db.Expando):
title = db.StringProperty()
lastEditedBy = db.ReferenceProperty(DocUser,collection_name ='documentLastEditedBy')
...

class DocUser(db.Model) :
user = db.UserProperty()
name = db.StringProperty()
hasWriteAccess = db.BooleanProperty(default = False)
isAdmin = db.BooleanProperty(default = False )
访问Groups = db.ListProperty(db.Key)
...

main .py

  $ out ='< table>'
documents = Document.all()
for i,d in enumerate(documents):
out + ='< tr>< td>%s< / td>< td>%s< / td>< / tr> ;'%(d.title,d.lastEditedBy.name)
$ out ='< / table>'


解决方案的一种方法是预取所有文件以创建查找字典,其中的键为docuser.key(),值为docuser.name。

  docusers = Docuser.all()。fetch(1000)
docuser_dict = dict([(i.key ),i.name)for i in docusers])

然后在你的代码中,你可以得到通过使用get_value_for_datastore来获取docuser.key()而不从数据存储拉取对象,从docuser_dict中获取名称。

  documents = Document 。所有()。取(1 000)
for i,d in enumerate(documents):
docuser_key = Document.lastEditedBy.get_value_for_datastore(d)
last_editedby_name = docuser_dict.get(docuser_key)
out + =' < tr>< td>%s< / td>< td>%s< / td>< / tr>'%(d.title,last_editedby_name)


When running the below with 200 Documents and 1 DocUser the script takes approx 5000ms according to AppStats. The culprint is that there is a request to the datastore for each lockup of the lastEditedBy (datastore_v3.Get) taking 6-51ms each.

What I'm trying do is to make something that makes possible to show many entities with several properties where some of them are derived from other entities. There will never be a large number of entities (<5000) and since this is more of an admin interface there will never be many simultaneous users.

I have tried to optimize by caching the DocUser entities but I am not able to get the DocUser key from the query above without making a new request to the datastore.

1) Does this make sense - is the latency I am experiencing normal?

2) Is there a way to make this work without the additional requests to the datastore?

models.py

class Document(db.Expando):
    title = db.StringProperty()
    lastEditedBy = db.ReferenceProperty(DocUser, collection_name = 'documentLastEditedBy')  
...

class DocUser(db.Model):
    user = db.UserProperty()
    name = db.StringProperty()  
    hasWriteAccess= db.BooleanProperty(default = False)
    isAdmin = db.BooleanProperty(default = False)
    accessGroups = db.ListProperty(db.Key)
...

main.py

$out = '<table>'   
documents = Document.all()
for i,d in enumerate(documents):        
    out += '<tr><td>%s</td><td>%s</td></tr>' % (d.title, d.lastEditedBy.name)
$out = '</table>'

解决方案

One way to do it is to prefetch all the docusers to make a lookup dictionary, with the keys being docuser.key() and values being docuser.name.

    docusers = Docuser.all().fetch(1000)
    docuser_dict = dict( [(i.key(), i.name) for i in docusers] )

Then in your code, you can get the names from the docuser_dict by using get_value_for_datastore to get the docuser.key() without pulling the object from the datastore.

    documents = Document.all().fetch(1000)
    for i,d in enumerate(documents):
        docuser_key = Document.lastEditedBy.get_value_for_datastore(d)
        last_editedby_name = docuser_dict.get(docuser_key)
        out += '<tr><td>%s</td><td>%s</td></tr>' % (d.title, last_editedby_name)

这篇关于如何减少对数据存储的请求数量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆