从数据库中查询满足我的过滤器查询的一条记录的最快方法是什么。
mydb.objects.filter(start__gte='2017-1-1', status='yes').order_by('?')[:1]
此语句将首先查询数千条记录然后选择一条记录,并且速度非常慢,但我只需要一条记录,一条随机记录。什么是最快的?
答案 0 :(得分:2)
使用order_by('?')
会导致性能问题。更好的方法是使用以下内容:Getting a random row from a relational database.
count = mydb.objects.filter(start__gte='2017-1-1', status='yes').aggregate(count=Count('id'))['count']
random_index = randint(0, count - 1)
result= mydb.objects.filter(start__gte='2017-1-1', status='yes')[random_index]
答案 1 :(得分:1)
嗯,我不确定你能不能做到你想要的。几个月前我遇到了类似的问题,最后我重新设计了我的后端实现,以使其工作。
基本上,您希望通过选择满足两个要求的随机记录(start__gte='2017-1-1', status='yes'
)来缩短查询时间,但就像您说的那样,为了使查询能够这样做,它需要过滤您的整个数据库。这意味着你无法得到一个真实的"来自数据库的也满足过滤器要求的随机记录,因为过滤本身需要查看所有记录(否则它不是真正随机的,它只是第一个它发现符合您的要求。)
相反,请考虑将具有status='yes'
的所有记录放在单独的关系中,以便您可以从那里提取随机记录并加入更大的关系。这将使查询时间大大加快(并且它是我为实现代码而实现的解决方案类型)。
如果您真的想要一个包含正确过滤信息的随机记录,您可能需要使用一些复杂的方法。
您可以在Django中使用custom manager让它只找到一条随机记录,如下所示:
class UsersManager(models.Manager):
def random(self):
count = self.aggregate(count=Count('id'))['count']
random_index = randint(0, count - 1)
return self.all()[random_index]
class User(models.Model):
objects = UsersManager()
#Your fields here (whatever they are, it seems start__gte and status are some)!
objects = UserManager()
您只需使用以下内容即可调用:
User.objects.random()
可以通过检查代码重复此操作,直到它返回满足您要求的随机记录。我认为这不一定是实现这一目标的最简洁或最正确的方法,但我不认为对于您的具体问题存在更快的解决方案。
我使用this site作为此答案的来源,并且它有更多关于使用此自定义随机方法的可靠信息!您可能需要更改自定义管理器以满足您自己的需求,但如果您将random()
方法添加到现有的自定义管理器,它应该能够满足您的需求!
希望它有所帮助!