我有一个叫Valor的模型。勇士有个机器人。我是这样查询的:
Valor.objects.filter(robot=r).reverse()[0]
得到最后的勇士和机器人。Valor.objects.filter(robot=r).count()大约是200000,在我的PC中获取最后一项大约需要4秒。
我怎么才能加快速度呢?我问错了吗?
发布于 2009-12-06 02:01:11
听起来你的数据集将会足够大,你可能想要稍微去规格化一下。您是否尝试过跟踪Robot对象中的最后一个Valor对象?
class Robot(models.Model):
# ...
last_valor = models.ForeignKey('Valor', null=True, blank=True)
然后使用post_save signal进行更新。
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查找将非常快。尝试一下,看看是否值得为你的应用程序做这样的权衡。
发布于 2011-11-30 23:15:26
解决这个问题的最佳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的slicing方法在编译对象列表之前限制查询集。
发布于 2009-12-06 01:26:18
如果前面的建议都不起作用,我建议把Django从方程式中去掉,在数据库上运行这个原始sql。我猜是您的表名,所以您可能需要相应地调整:
SELECT * FROM valor v WHERE v.robot_id = [robot_id] ORDER BY id DESC LIMIT 1;
是不是很慢?如果是这样的话,让你的关系型数据库管理系统(MySQL?)向您解释查询计划。这将告诉您它是否正在执行任何全表扫描,对于这么大的表,您显然不希望这样做。您还可以编辑您的问题,并包含valor
表的模式以供我们查看。
此外,您还可以通过执行以下操作(使用Peter Rowell提供的查询集)查看Django生成的SQL:
qs = Valor.objects.filter(robot=r).order_by('-id')[0]
print qs.query
确保SQL类似于我在上面发布的“原始”查询。您还可以让RDBMS向您解释该查询计划。
https://stackoverflow.com/questions/1852738
复制相似问题