2015-09-04 56 views
1

我需要找到一個序列號和對象的列表,每個人有一個序列號之間的匹配:查詢集優化

型號:

class Beacon(models.Model): 
    serial = models.CharField(max_length=32, default='0') 

首先,我寫道:

for b in Beacon.objects.all(): 
     if b.serial == tmp_serial: 
      # do something 
      break 

然後我做了先行一步:

b_queryset = Beacon.objects.all().filter(serial=tmp_serial) 
    if b_queryset.exists(): 
     #do something 

現在,是否有更多優化的第二步?

我不認爲將我的QuerySet強制轉換爲List並執行list.index('tmp_serial')會更快。

回答

0

如果你的序列是唯一的,你可以做:

# return a single instance from db 
match = Beacon.objects.get(serial=tmp_serial) 

如果你有多個對象用sa我的序列和計劃在他們每個人上做些事情,存在會添加一個無用的查詢。 相反,你應該做的:

matches = Beacon.objects.filter(serial=tmp_serial) 

if len(matches) > 0: 
    for match in matches: 
     # do something 

的這裏訣竅是,len(matches)將迫使查詢集的評估(所以你的數據庫將被查詢)。之後,檢索 模型實例,您可以在不使用其他查詢的情況下使用它們。

但是,當您使用queryset.exists()時,ORM運行一個非常簡單的查詢來檢查查詢集是否會返回任何元素。然後,如果您迭代您的查詢集,則運行另一個查詢來獲取您的對象。有關更多詳細信息,請參見the related documentation

綜上所述:僅當您想要檢查查詢集是否返回結果時才使用exists。如果您確實需要查詢集數據,請使用len()

+0

謝謝,非常有幫助。你認爲exists()是否超快?如果exists()返回True,那麼首先執行exists()然後獲取對象是否是個好主意? – bixente57

+0

存在確實超快,但如果你需要這些對象,直接獲取它們,不要使用存在。它會爲您節省一個查詢。 –

0

我認爲你是在最好的,但如果你只是想對象是否存在還是不那麼,

從Django的查詢集exists() https://docs.djangoproject.com/en/1.8/ref/models/querysets/#django.db.models.query.QuerySet.exists

if Beacon.objects.all().filter(serial=tmp_serial).exists(): 
     # do something 
+0

不幸的是我必須得到對象本身 – bixente57

+0

然後你在這種情況下做得最好。如果您發現它有幫助並解決您的問題,請接受答案。 –

+0

你仍然可以從兩個查詢移動到一個,看到我的答案 –