首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >快速查找Django QuerySet中的最后一个元素?

快速查找Django QuerySet中的最后一个元素?
EN

Stack Overflow用户
提问于 2009-12-06 01:00:34
回答 9查看 10.5K关注 0票数 10

我有一个叫Valor的模型。勇士有个机器人。我是这样查询的:

代码语言:javascript
运行
复制
Valor.objects.filter(robot=r).reverse()[0]

得到最后的勇士和机器人。Valor.objects.filter(robot=r).count()大约是200000,在我的PC中获取最后一项大约需要4秒。

我怎么才能加快速度呢?我问错了吗?

EN

回答 9

Stack Overflow用户

回答已采纳

发布于 2009-12-06 02:01:11

听起来你的数据集将会足够大,你可能想要稍微去规格化一下。您是否尝试过跟踪Robot对象中的最后一个Valor对象?

代码语言:javascript
运行
复制
class Robot(models.Model):
    # ...
    last_valor = models.ForeignKey('Valor', null=True, blank=True)

然后使用post_save signal进行更新。

代码语言:javascript
运行
复制
from django.db.models.signals import post_save

def record_last_valor(sender, **kwargs):
    if kwargs.get('created', False):
        instance = kwargs.get('instance')
        instance.robot.last_valor = instance

post_save.connect(record_last_valor, sender=Valor)

当您创建Valor对象时,您将支付额外的db事务的成本,但last_valor查找将非常快。尝试一下,看看是否值得为你的应用程序做这样的权衡。

票数 4
EN

Stack Overflow用户

发布于 2011-11-30 23:15:26

解决这个问题的最佳mysql语法应该是这样的:

代码语言:javascript
运行
复制
SELECT * FROM table WHERE x=y ORDER BY z DESC LIMIT 1

django的等价物是:

代码语言:javascript
运行
复制
Valor.objects.filter(robot=r).order_by('-id')[:1][0]

注意这个解决方案如何利用django的slicing方法在编译对象列表之前限制查询集

票数 8
EN

Stack Overflow用户

发布于 2009-12-06 01:26:18

如果前面的建议都不起作用,我建议把Django从方程式中去掉,在数据库上运行这个原始sql。我猜是您的表名,所以您可能需要相应地调整:

代码语言:javascript
运行
复制
SELECT * FROM valor v WHERE v.robot_id = [robot_id] ORDER BY id DESC LIMIT 1;

是不是很慢?如果是这样的话,让你的关系型数据库管理系统(MySQL?)向您解释查询计划。这将告诉您它是否正在执行任何全表扫描,对于这么大的表,您显然不希望这样做。您还可以编辑您的问题,并包含valor表的模式以供我们查看。

此外,您还可以通过执行以下操作(使用Peter Rowell提供的查询集)查看Django生成的SQL:

代码语言:javascript
运行
复制
qs = Valor.objects.filter(robot=r).order_by('-id')[0]
print qs.query

确保SQL类似于我在上面发布的“原始”查询。您还可以让RDBMS向您解释该查询计划。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1852738

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档