如何用数据库查询改善python代码的时间

时间:2017-11-08 11:50:43

标签: python mysql ajax django

我在Django 1.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") 但这没有帮助。

1 个答案:

答案 0 :(得分:1)

主要问题是您在循环中运行查询。你可以做的是在一个查询中获取所有对象,然后在循环中使用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)