perf: 优化has_envdata的sql查询2

This commit is contained in:
caoqianming 2025-02-13 13:26:32 +08:00
parent 61f9dc3b51
commit d7361a71df
2 changed files with 33 additions and 10 deletions

View File

@ -15,8 +15,8 @@ from django.db import transaction
from apps.em.services import daoru_equipment
from rest_framework.response import Response
from django.conf import settings
from django.db.models import Count, Case, When, IntegerField, Max, OuterRef, Subquery
from datetime import datetime, timedelta
from django.db.models import Count, Case, When, IntegerField
from apps.enp.services import get_last_envdata
# Create your views here.
@ -75,13 +75,11 @@ class EquipmentViewSet(CustomModelViewSet):
if self.request.query_params.get("has_envdata", "no") == "yes":
now = timezone.localtime()
now_10_before = now - timezone.timedelta(minutes=10)
data_ids = [item["id"] for item in data]
from apps.enp.models import EnvData
from apps.enp.serializers import EnvDataSerializer
edata_qs = EnvData.objects.filter(equipment_id__in=data_ids, timex__gte=now_10_before, timex__lte=now).order_by("timex")
edata = EnvDataSerializer(edata_qs, many=True).data
edata_dict = {item["equipment"]: item for item in edata}
edata_dict = {}
if data:
data_ids = [item["id"] for item in data]
edata = get_last_envdata(data_ids, now_10_before, now)
edata_dict = {item["equipment"]: item for item in edata}
for item in data:
item["envdata"] = edata_dict.get(item["id"], {})
return data

View File

@ -1 +1,26 @@
from openpyxl import load_workbook
from apps.enp.models import EnvData
from apps.enp.serializers import EnvDataSerializer
from datetime import datetime
def get_last_envdata(eIds: list, time_start: datetime, time_end: datetime):
eIds_str = ",".join([f"'{item}'" for item in eIds]) # 将 ID 列表格式化为字符串
time_start_str = time_start.strftime("%Y-%m-%d %H:%M:%S")
time_end_str = time_end.strftime("%Y-%m-%d %H:%M:%S")
esql = f'''
SELECT DISTINCT ON (equipment_id) *
FROM enp_envdata ee
WHERE equipment_id IN ({eIds_str})
AND timex AT TIME ZONE 'Asia/Shanghai' >= '{time_start_str}'
AND timex AT TIME ZONE 'Asia/Shanghai' <= '{time_end_str}'
ORDER BY equipment_id, timex DESC
'''
edata = EnvDataSerializer(EnvData.objects.raw(esql), many=True).data
# esql ='''SELECT DISTINCT ON (equipment_id) *
# FROM enp_envdata ee
# WHERE equipment_id IN %s
# AND timex AT TIME ZONE 'Asia/Shanghai' >= %s
# AND timex AT TIME ZONE 'Asia/Shanghai' <= %s
# ORDER BY equipment_id, timex DESC'''
# res = query_all_dict(esql, [tuple(data_ids), now_10_before_str, now_str])
return edata