如何通过数据库查询提高python代码的运行时间

2024-09-27 17:50:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我在django1.11中有一些数据库查询,大约需要40秒,我想提高速度,但我的想法已经过时了。 我想创建一个图表,其中有6个图表,其中包含数据,无需等待40秒

这是模型:

from django.db import models

class MinutenReserveLastYear(models.Model):
    datum = models.DateField()
    produkt = models.CharField(max_length=100)
    grenz_lp = models.FloatField()
    mittl_lp = models.FloatField()

    class Meta:
        indexes = [
            models.Index(fields=['datum', 'produkt']),
        ]

我发出一个Ajax请求来获取数据:

var neg_last_year = $.ajax({
     method: "POST",
     url: "/prognose/minutenreserve/data/",
     data: { "produkt": "NEG", "zeitraum": "last_year" },
     dataType: "json",
     context: this
});

从数据库获取数据的视图函数:

from .models import MinutenReserveLastYear

def minutenreserve_data(request):
    if request.method == "POST":
    produkt_group = request.POST.get("produkt")
    zeitraum = request.POST.get("zeitraum")
    datum_list = {}
    grenz_lp = {}
    mittl_lp = {}

    if zeitraum == "last_year":
        if produkt_group == "NEG":
            produkt_list = ["NEG_00_04", "NEG_04_08", "NEG_08_12", "NEG_12_16", "NEG_16_20", "NEG_20_24"]
            dataset = MinutenReserveLastYear.objects
            last_year = datetime.date.fromtimestamp(datetime.datetime.timestamp(
                datetime.datetime.now() - datetime.timedelta(weeks=52))).year
            days = (datetime.date(last_year, 12, 31) - datetime.date(last_year, 1, 1)).days
            for j in range(6):
                grenz_lp[j] = []
                mittl_lp[j] = []
                datum_list[j] = []
                produkt = produkt_list[j]
                for i in range(days+1):
                    datum = datetime.date(last_year, 1, 1) + datetime.timedelta(days=i)
                    datum_list[j] += [datum.strftime('%d.%m.%Y')]
                    grenz_lp[j] += [dataset.filter(datum=datum, produkt=produkt).values_list()[0][3]]
                    mittl_lp[j] += [dataset.filter(datum=datum, produkt=produkt).values_list()[0][2]]
            data = {'datum_list': datum_list, 'grenz_lp': grenz_lp, 'mittl_lp': mittl_lp}
            return JsonResponse(data)

当Ajax请求完成时:

$.when(neg_last_year).done(function(data) {
    var datum_list = data.datum_list[0];
    var grenzlp_00_04 = data.grenz_lp[0];
    var grenzlp_04_08 = data.grenz_lp[1];
    var grenzlp_08_12 = data.grenz_lp[2];
    var grenzlp_12_16 = data.grenz_lp[3];
    var grenzlp_16_20 = data.grenz_lp[4];
    var grenzlp_20_24 = data.grenz_lp[5];
    var neg_last_year = document.getElementById('NEG_LAST_YEAR').getContext('2d');
    var chart_neg_last_year = new Chart(neg_last_year, {
        type: 'line',
        data: {
            labels: datum_list,
            datasets: [datasets]
            },
            options: options
        })
});

我怀疑问题出在通过循环的许多数据库查询中。如何加速代码? 如何减少数据库查询的数量

编辑:

我试图通过使用

dataset = MinutenReserveLastYear.objects.prefetch_related("grenz_lp", "mittl_lp") 但这没有帮助


Tags: datadatetimemodelsvaryearlistlastlp
1条回答
网友
1楼 · 发布于 2024-09-27 17:50:58

主要问题是您在循环中运行查询。您可以在一个查询中获取所有对象,然后在循环中使用if-else过滤对象

解决方案

dataset = MinutenReserveLastYear.objects.all()

for j in range(6):
    grenz_lp[j] = []
    mittl_lp[j] = []
    datum_list[j] = []
    produkt = produkt_list[j]
    for i in range(days+1):
        datum = datetime.date(last_year, 1, 1) + datetime.timedelta(days=i)

        for data in dataset:
            if data.datum == datum and data.produkt == produkt:
                grenz_lp[j].append(data.grenz_lp)
                mittl_lp[j].append(data.mittl_lp)

相关问题 更多 >

    热门问题