我正在使用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)。
答案 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)
要使这些查询有效,您必须age
和dob
列create indexes。
使用covering indexes即可获得额外的加速,即使用包含height
列的双列索引。