Kne*_*ewB 3 django django-models
我正在评估一个QuerySet,然后是另一个,但第二个是第一个的子集.我正在尝试以有效的方式执行此操作,尽可能少的数据库调用.(之前有人问过,但说实话,我并不完全理解答案,我不确定它们是否完全适用于我正在考虑的事情.)
使用Django doc的示例Weblog模型,在视图中,这是在尝试优化之前的代码:
myblog = Blog.objects.get(pk=1)
d={} #going to pass this to my template
# not using count()
d['num_of_entries'] = len(myblog.entry_set.all())
# not using exists()
d['is_jolly'] = bool(Entry.objects.filter(blog=myblog, headline__startswith='Jolly'))
# ... other code but no further use of database in this view
Run Code Online (Sandbox Code Playgroud)
第二个QuerySet是第一个QuerySet的子集.我应该尝试使用纯Python来获取子集(因此只评估一个QuerySet - 一个较少的数据库调用)?
或者,或许只是做以下事情?
# other code as above
d['num_of_entries'] = myblog.entry_set.count()
d['is_jolly'] = Entry.objects.filter(blog=myblog, headline__startswith='Jolly').exists()
# ... other code but no further use of database in this view
Run Code Online (Sandbox Code Playgroud)
"尽可能少的数据库查询"不是正确的标准.您还要考虑这些数据库查询所完成的工作量,以及从数据库传输到Django服务器的数据量.
让我们考虑实现你所追求的两种方式.方法1:
entries = myblog.entry_set.all()
num_of_entries = len(entries)
is_jolly = any(e.headline.startswith('Jolly') for e in entries)
Run Code Online (Sandbox Code Playgroud)
方法2:
num_of_entries = myblog.entry_set.count()
is_jolly = Entry.objects.filter(blog=myblog, headline__startswith='Jolly').exists()
Run Code Online (Sandbox Code Playgroud)
在方法1中,有一个数据库查询,但该查询将是类似的SELECT * FROM ENTRY WHERE ....它可能会获取大量条目,并将所有内容通过网络传输到您的Django服务器,然后将几乎所有内容丢弃(实际上唯一看到的headline字段是字段).
方法2中有两个数据库查询,但第一个是SELECT COUNT(*) FROM ENTRY WHERE ...仅获取一个整数的第二个,第二个是SELECT EXISTS(...)仅获取一个布尔值的数据查询.由于这些查询不必获取所有匹配条目,因此数据库可以更多地优化查询.
因此,在这种情况下,方法2看起来要好得多,即使它发出更多查询.
| 归档时间: |
|
| 查看次数: |
937 次 |
| 最近记录: |