我试图从我的查询集中抽取一些记录来表现如下:
from random import sample
from my_app import MyModel
my_models = MyModel.objects.all()
# sample only a few of records for performance
my_models_sample = sample(my_models, 5)
for model in my_models_sample:
model.some_expensive_calculation
但我觉得它在执行时间方面只会变得更糟。
random.sample()
如何在幕后工作?它会对django查询集产生相当大的性能负担吗?
答案 0 :(得分:4)
由于random.sample()
将强制评估查询集my_models
,因此程序的执行时间将在很大程度上取决于数据库中MyModel
个对象的总数。
为了提高性能并避免将整个查询集加载到内存中,您最终可能会按照here和.iterator()
方法一起实现自己的采样功能。
或者,您也可以依靠数据库服务器通过order_by('?')
为您进行采样,如下所示:
MyModel.objects.order_by('?')[:5]
就个人而言,我不建议使用后者,因为查询可能很昂贵而且速度很慢,具体取决于您使用的数据库后端。 (特别是对于MySQL)
答案 1 :(得分:1)
为什么不让数据库进行改组和限制并比较时间?
MyModel.objects.order_by('?')[:5]
尽管the documentation声明这可能很昂贵,但就你的情况而言,无论如何都要提取所有行,我怀疑会有所不同。差异的大小取决于数据集的大小(当然还有数据库后端)。
答案 2 :(得分:1)
您在QuerySet对象上使用random.sample()
。
如果您确实希望获得5个随机样本作为QuerySet,那么您可以使用此
random_objects = MyModel.objects.all().order_by('?')[:5]
这将为您提供5个随机对象并缩短您的采样时间。
PS:我还将检查为什么random.sample()
需要花费这么多时间来进行该操作,如果我找到了什么,我也会检查这个问题。 :)