2017-07-13 129 views
0

什麼是查詢從數據庫中一個記錄是滿足我的篩選查詢以最快的方式隨機查詢一個記錄的最快方式。Django的:使用過濾器

mydb.objects.filter(start__gte='2017-1-1', status='yes').order_by('?')[:1] 

此聲明將首先查詢數千條記錄,然後選擇一條,它非常慢,但我只需要一條,隨機的一條。什麼是最快得到的?

+0

我確實在乎我抓的是什麼,我需要一個隨機的。它不可能一直是同一個。 – jifferent

回答

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()方法添加到現有的自定義管理器中,它應該能夠滿足您的需求!

希望它有幫助!

+1

謝謝,真正的隨機在我的設計中會非常困難,而且django中的order_by('?')真的很痛苦。這會幫助我很多。 – jifferent

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]