django查询聚合函数是慢吗?

时间:2017-09-14 19:54:02

标签: django sqlite aggregate django-queryset

我正在使用Django来了解如何处理大型数据库。我使用的数据库包含字段名称,年龄,出生日期(dob)和身高。该数据库有大约500000个条目。我必须找到(1)相同年龄和(2)同年出生的人的平均身高。查询表中的聚合函数大约需要10秒。这是常见的还是我错过了什么?

适合年龄:

age = [i[0] for i in Data.objects.values_list('age').distinct()]
ht = []
for each in age:
    aggr = Data.objects.filter(age=each).aggregate(ag_ht=Avg('height')
    ht.append(aggr)

来自dob,

age = [i[0].year for i in Data.objects.values_list('dob').distinct()]
for each in age:
    aggr = Data.objects.filter(dob__contains=each).aggregate(ag_ht=Avg(‌​'height')
    ht.append(aggr)

这一年必须从dob中提取。它是SQLite,我不能使用__year(join)。

2 个答案:

答案 0 :(得分:0)

完整版带时间比较循环和查询集版本

import time
from dd.models import Data
from django.db.models import Avg
from django.db.models.functions import ExtractYear

适合年龄

start = time.time()
age = [i[0] for i in Data.objects.values_list('age').distinct()]
ht = []

for each in age:
    aggr = Data.objects.filter(age=each).aggregate(ag_ht=Avg('height'))
    ht.append(aggr)

end = time.time()
loop_time = end - start

start = time.time()
qs = Data.objects.values('age').annotate(ag_ht=Avg('height')).order_by('age')
ht_qs = qs.values_list('age', 'ag_ht')
end = time.time()
qs_time = end - start

print loop_time / qs_time

for dob year,轻松重构您的版本(多年来添加设置)

start = time.time()
years = set([i[0].year for i in Data.objects.values_list('dob').distinct()])
ht_year_loop = []
for each in years:
    aggr = Data.objects.filter(dob__contains=each).aggregate(ag_ht=Avg('height'))
    ht_year_loop.append((each, aggr.get('ag_ht')))

end = time.time()
loop_time = end - start

start = time.time()
qs = Data.objects.annotate(dob_year=ExtractYear('dob')).values('dob_year').annotate(ag_ht=Avg('height'))
ht_qs = qs.values_list('dob_year', 'ag_ht')
end = time.time()
qs_time = end - start

print loop_time / qs_time

答案 1 :(得分:0)

要使这些查询有效,您必须agedobcreate indexes

使用covering indexes即可获得额外的加速,即使用包含height列的双列索引。