Jua*_*nti 10 django optimization django-queryset
我有一个叫做Valor的模特.勇气有一个机器人.我这样查询:
Valor.objects.filter(robot=r).reverse()[0]
让最后一个Valor成为r机器人.Valor.objects.filter(robot = r).count()约为200000,在我的电脑中获取最后一项约需4秒.
我怎样才能加快速度?我在查询错误的方式?
这个问题的最佳mysql语法将是:
SELECT * FROM table WHERE x=y ORDER BY z DESC LIMIT 1
与此相当的django将是:
Valor.objects.filter(robot=r).order_by('-id')[:1][0]
请注意此解决方案如何利用django的切片方法在编译对象列表之前限制查询集.
如果以前的建议都没有起作用,我建议将Django从等式中取出并对你的数据库运行这个原始的sql.我猜你的桌名,所以你可能需要相应调整:
SELECT * FROM valor v WHERE v.robot_id = [robot_id] ORDER BY id DESC LIMIT 1;
这慢吗?如果是这样,让您的RDBMS(MySQL?)向您解释查询计划.这将告诉您它是否正在进行任何全表扫描,您显然不希望使用大表.您也可以编辑您的问题并包含valor表格的架构供我们查看.
此外,您可以通过执行此操作来查看Django生成的SQL(使用Peter Rowell提供的查询集):
qs = Valor.objects.filter(robot=r).order_by('-id')[0]
print qs.query
确保SQL类似于我上面发布的"原始"查询.您还可以让您的RDBMS向您解释该查询计划.
听起来您的数据集将足够大,您可能想要稍微非规范化一些东西。您是否尝试过跟踪 Robot 对象中的最后一个 Valor 对象?
class Robot(models.Model):
    # ...
    last_valor = models.ForeignKey('Valor', null=True, blank=True)
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 对象时,您将支付额外的数据库事务成本,但 last_valor 查找将非常快。尝试一下,看看这种权衡对于您的应用程序是否值得。
| 归档时间: | 
 | 
| 查看次数: | 9640 次 | 
| 最近记录: |