2015-09-04 66 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

你仍然可以从两个查询移动到一个,看到我的答案 –