在我正在处理的Python GAE应用程序中,我们需要从存储中检索n行,并且我们遇到n>的性能问题。我们希望在大多数情况下n小于10000。
因此,让我们考虑一个简单的模型:
class MyEntity(ndb.Model):
field1 = nbd.StringProperty()
field2 = ndb.StringProperty()
#...
fieldm = ndb.StringProperty()
# m is quite large, maybe ~ 30. Stored strings are short - in the order of 30 characters or less
我已经使用一些数据填充了数据存储,并且使用普通fetch()
获得了非常糟糕的性能。我已经删除了所有过滤器,并且只是尝试获取许多实体似乎会获得非常糟糕的性能(与我期望的任何常见SQL部署相比。我知道我们不应该这样做。将GAE与SQL进行比较,但只是将平行排成一行 - 我希望它的性能更高,而不是更低。以下是我尝试过的内容:
MyEntity.all().fetch(n)
。这与n
呈线性关系,这是预期的。虽然我没想到n = 1000
需要7分。fetch()
任何合理的batch_size
进一步降低性能。我尝试过的值介于1到1000之间。keys_only
可以提高数量级。 through ndb.Query
),只取出一个字段可以得到一个很小的改进,大约为1.2。fetch_async(n)
并等待提供完全相同的效果。p
部分,然后执行fetch_async(n/p, offset=...)
,然后等待并加入所有期货 - 最好提供相同的性能,最糟糕的是 - 性能要差得多。fetch_page()
我还尝试使用db
代替ndb
,结果几乎相同。那么,现在我不知道该怎么办?有没有办法让10000 {10000}的n
获得一半不错的表现?即使将我的实体简化为单个字段,性能也太差。我希望未压缩的整个有效载荷大约为1 mb。在一分钟内下载1mb显然是不可接受的。
我现在看到这个问题,但是对于性能测试,我使用的是远程api。我的问题类似于关于SO的这个问题:Best practice to query large number of ndb entities from datastore。他们似乎没有找到解决方案,但4年前有人问过,也许现在有一个。
答案 0 :(得分:1)
如果您只需要模型的字段子集,请查看Projection Queries
答案 1 :(得分:1)
您可以获得更好的性能,具体取决于您需要对检索到的数据执行的操作。例如,使用您提到的_async
documentation here。您可以检索数据的子集,比如前100,然后在处理第一个数据批处理时,在100个记录的下一个子集上调用_async
,因为_async
是非阻塞的。在进行结束时,使用.get_result()
检索第二批结果并开始处理其数据,同时使用_async
...等调用第三批。