简体   繁体   English

Django Queryset加载时间太长

[英]Django Queryset take too long to load

I just uploaded a project to my server on digital ocean. 我刚刚将项目上传到数字海洋上的服务器。 When I load the Partnership view it takes about 1 minute before the data is queried and filtered an d then displayed. 加载合作伙伴视图时,大约需要1分钟才能查询和过滤数据,然后显示d。 There are 1,905,120 entries to be filtered to display about 200,000 entries. 有1,905,120个条目要过滤以显示约200,000个条目。 How can I optimize the process? 如何优化流程?

views.py views.py

class PartnershipView(LoginRequiredMixin, generic.ListView): 
model = Partnership
slug = ''
slug1 = ''
slug2 = ''

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    slug = self.kwargs.get("slug")
    slug1 = self.kwargs.get("slug1")
    slug2 = self.kwargs.get("slug2")

    currentYear = datetime.datetime.now().year
    currentMonth = calendar.month_name[datetime.datetime.now().month]
    partnershipArms = PartnershipArm.objects.all()

    context['partnershipArms'] = partnershipArms


    partnershipArm = PartnershipArm.objects.get(slug = slug)

    if slug =='':
        partnerships = self.get_queryset().filter(partnershipArm = partnershipArm, year=currentYear, month = currentMonth )
    else:
        partnerships = self.get_queryset().filter(partnershipArm = partnershipArm, year=slug1, month = slug2 )
    members = Member.objects.all()

    context['currentYear'] = currentYear
    context['currentMonth'] = currentMonth
    context['partnershipArmName'] = partnershipArm.name
    context['partnershipArm'] = slug
    context['partnerships'] = partnerships
    context['members'] = members
    context['year'] = slug1
    context['month'] = slug2

    return context

partnership_list.html partnership_list.html

<table id="datatable-buttons" class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>Name</th>
            <th>contact</th>
            <th>Email</th>
            <th>Week 1</th>
            <th>Week 2</th>
            <th>Week 3</th>
            <th>Week 4</th>
            <th>Total</th>
        </tr>
    </thead>

    <tbody>
    {% for instance in partnerships %}
        <tr>
        {% for member in members %}
        {% if member.pk == instance.member_id %}
            <td>{{ member.title }} {{ member.fname }} {{ member.lname }}</td>
            <td>{{ member.contact }}</td>
            <td>{{ member.email }}</td>
        {% endif %}
        {% endfor%}
            <td><a href="{% url 'partnership-week1-update' partnershipArm instance.pk %}">{{instance.week1 }}</a></td>
            <td><a href="{% url 'partnership-week2-update' partnershipArm instance.pk %}">{{ instance.week2 }}</a></td>
            <td><a href="{% url 'partnership-week3-update' partnershipArm instance.pk %}">{{ instance.week3 }}</a></td>
            <td><a href="{% url 'partnership-week4-update' partnershipArm instance.pk %}">{{ instance.week4 }}</a></td>
            <td>{{ instance.total }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>

models.py models.py

class PartnershipArm(models.Model):
name = models.CharField(max_length = 128)
slug = models.SlugField(unique = True, null=True, blank=True)
partnershipRecords = models.ManyToManyField(Member, through = 'Partnership') 

def __str__(self):
    return self.name

def get_absolute_url(self):
    return reverse('partnership-arms')

class Partnership(models.Model):

YEAR = []
for r in range((datetime.datetime.now().year), (datetime.datetime.now().year+10)):
    YEAR.append((r,r))
MONTHS = (
    ('January', 'January'),
    ('February', 'February'),
    ('March', 'March'),
    ('April', 'April'),
    ('May', 'May'),
    ('June', 'June'),
    ('July', 'July'),
    ('August', 'August'),
    ('September', 'September'),
    ('October', 'October'),
    ('November', 'November'),
    ('December', 'December'),
)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
partnershipArm = models.ForeignKey(PartnershipArm, on_delete=models.CASCADE)
year = models.IntegerField( choices=YEAR, default=datetime.datetime.now().year)
month = models.CharField(max_length = 50, choices = MONTHS, null=True, blank=True)
week1 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week2 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week3 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
week4 = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
total = models.DecimalField(max_digits=10, decimal_places=2, default = 0)
#keyChecker = models.CharField(max_length=250,unique=True, null=True, blank=True)

def __str__(self):
    return "{0}_{1}_{2}_{3}".format(self.member, self.partnershipArm, self.year, self.month)

def get_absolute_url(self):
    return reverse('partnership-arms')

You have not posted your models but you should make sure to set a database index ( db_index = True ) on each of these fields as you are using them in a filter() : partnershipArm , year and month . 您尚未发布模型,但是当您在filter()中使用它们时,请确保在每个字段上都设置数据库索引db_index = True filter()partnershipArmyearmonth

Furthermore it is of course not the recommended way to display all the data on one page, you should rater use some sort of pagination if your use case allows to do so. 此外,当然也不建议将所有数据显示在一页上,如果用例允许的话,您应该评价使用某种分页

In the template you are iterating through the members to find the right member for your partnership instance. 在模板中,您正在遍历成员以找到适合您的伙伴关系实例的成员。 If you have low number of members this might already be the faster way than using select_related('member') and accessing instance.member directly, but I would say this depends a lot on the number of members/partnerships in your database. 如果您的成员数量很少,这可能已经比使用select_related('member')和直接访问instance.member更快的方法,但是我想说这很大程度上取决于数据库中成员/合伙关系的数量。 If you still want to load the members in a seperate database query it would of course be the faster way to organize them in a dict with the id as the key so that you dont have to iterate over them for every row. 如果您仍然希望在单独的数据库查询中加载成员,那么这当然是将其组织为以id为键的dict中更快的方式,这样您就不必为每一行都遍历它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM