我有两个这样的模型:
class MyDevice(models.Model):
device_id = models.AutoField(primary_key=True)
insert_time = models.DateTimeField(auto_now_add=True)
update_time = models.DateTimeField(auto_now=True)
class MyDeviceMeasurement(models.Model):
device_id = models.AutoField(primary_key=True)
insert_time = models.DateTimeField(auto_now_add=True) -> Indexed
update_time = models.DateTimeField(auto_now=True)
parent_device = models.ForeignKey(MyDevice, on_delete=models.CASCADE, null=False, blank=False,
data = JSONField(null=False, blank=False, verbose_name="Data from device")
现在,我想执行一个子查询,该子查询将MyDevice
表中最新的测量值data
属性注释到MyDeviceMeasurement
模型。
因此,我尝试遵循有关subqueries的官方Django Docs,并且实现了以下查询:
MyDevice.objects.annotate(
latest_measurement=Subquery(
MyDeviceMeasurement.objects.filter(parent_device=OuterRef('device_id')).order_by(
'-insert_time').values('data')[:1]))
但是,不幸的是,查询非常非常慢(MyDeviceMeasurement
查询集统计了数百万行):57秒才能完成。
相反,每个MyDevice
使用一个简单的python foor循环并按日期排序来获取最新的MyDeviceMeasurement
对象,这非常快,每10台设备总共总计20毫秒大约需要120毫秒。
这很奇怪,我不知道为什么。
######## UPDATE使用这种方法(多次查询),我已经能够解决该问题,但是在任何情况下,使用Subquery / Join方法,即使我添加了一些新的索引,该问题仍然存在。他们等等...
result_list = []
for smartdev in MyDevice.objects.all():
try:
latest_measurement = smartdev.data_set.latest()
smartdev.latest_measurement = latest_measurement.data
except MyDeviceMeasurement.DoesNotExist:
pass
result_list.append(smartdev)
真的,我不知道为什么!