Python Django:如何计算查询集并返回一个切片,而不必两次命中DB?

Python Django:如何计算查询集并返回一个切片,而不必两次命中DB?,python,mysql,django,Python,Mysql,Django,我的API中包含这部分代码,这部分代码最近已成为一个瓶颈: total = results.count() if request.GET.has_key('offset'): offset = int(request.GET.get('offset').strip()) results = results.order_by('name')[100*offset:100*(offset+1)] people = list(results) 请注意,results是所有人的查询集,

我的API中包含这部分代码,这部分代码最近已成为一个瓶颈:

total = results.count()
if request.GET.has_key('offset'):
    offset = int(request.GET.get('offset').strip())
    results = results.order_by('name')[100*offset:100*(offset+1)]
people = list(results)

请注意,
results
是所有人的查询集,
offset
是用于分页的参数

在这里,当我打印时,我可以看到我的数据库被
.count()
列表(结果)
两次命中。为什么
.count()
必须在顶部,因为我需要知道所有人的长度(不是100)。有没有办法绕过这个问题?

可能是这样的

allpeople = list(results.order_by('name'))
total = len(allpeople)
if request.GET.has_key('offset'):
    offset = int(request.GET.get('offset').strip())
    results = allpeople[100*offset:100*(offset+1)]
people = results

请记住,
people=results
将在请求时失败。获取:不会触发。

您在哪里使用
total
?,但我不知道如何使用django来利用它,我也不确定其他数据库是否支持它。@JonasWielicki这是否会大大加快事情的发展,这是有争议的;请参阅:–解决此问题的更好方法可能是首先了解为什么这些查询花费的时间太长。适当的索引可以帮你走很长的路。OP,你有没有测试过为什么这些查询花费的时间太长?当您需要两个查询时尝试进行一个查询似乎是显而易见的解决方案,但这并不意味着它是唯一的(甚至是最好的)一个。在进行性能优化时,你应该首先信任基准,而不是直觉。与@ThomasOrozco所说的不同,-TLDR:如果你将其用于
order\u by
的话,你可以初始化结果,比如
results=allpeople=list(结果…
在您的第一行中删除您的最终警告。我不同意这个答案,因为我们不知道返回的结果的数量。在
列表()中包装查询集
导致对其进行评估,并将所有结果存储在内存中。如果您有数百万个结果,这可能是灾难性的。这最近发生在我身上,所以我根据经验说话。您是对的。事实上,这比我对一百万条记录进行基准测试时要慢。但是,它完全解决了避免两次命中数据库的问题…事实证明@ThomasOrozco是正确的,更少的查询可能并不总是更快。顺便说一句,
name
索引从一开始就一直存在。