django 按年月统计文章的数量sql语句优化 速度提高30倍

前端之家收集整理的这篇文章主要介绍了django 按年月统计文章的数量sql语句优化 速度提高30倍前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

使用Django Debug Toolbar发现统计不同年月之间发布的文章数量这句sql语句非常耗时,需要将近2100ms,于是决定优化其sql。从代码可以知道,老版代码提取article表所有的数据,在数据量过小时,sql语句速度不是太大问题。一旦数据量过大,性能将极速下降,因为用的很多不必要的字段。

代码

articles = Article.objects.all()
year_month = set()  # 设置集合,无重复元素
for a in articles:
    year_month.add((a.pub_date.year, a.pub_date.month))  # 把每篇文章的年、月以元组形式添加到集合中
counter = {}.fromkeys(year_month, 0)  # 以元组作为key,初始化字典

for a in articles:
    counter[(a.pub_date.year, a.pub_date.month)] += 1  # 按年月统计文章数目

year_month_number = []  # 初始化列表
for key in counter:
    year_month_number.append([key[0], key[1], counter[key]])  # 把字典转化为(年,月,数目)元组为元素的列表
year_month_number.sort(reverse=True)  # 排序

优化后代码

利用MysqL中ExtractYear,ExtractMonth

from django.db.models.functions import ExtractYear, ExtractMonth
from django.db.models import Count

count_dict = Article.objects.annotate(year=ExtractYear('pub_date'), month=ExtractMonth('pub_date')) \
    .values('year', 'month').order_by('year', 'month').annotate(count=Count('id'))
"""
count_dict 数据样例
<QuerySet [{'year': 2018, 'month': 7, 'count': 3}, {'year': 2019, 'month': 5, 'count': 7}, 'month': 6, 'count': 161}]>

"""
year_month_number = []  # 初始化列表
for key in count_dict:
    year_month_number.append([key['year'], key['month'], key['count']])  # 把字典转化为(年,月,数目)元组为元素的列表
year_month_number.sort(reverse=True)  # 排序

sql语句:

SELECT EXTRACT(MONTH FROM `article`.`pub_date`) AS `month`,       EXTRACT(YEAR FROM `article`.`pub_date`) AS `year`,       COUNT(`article`.`id`) AS `count`
  FROM `article`
 GROUP BY EXTRACT(MONTH FROM `article`.`pub_date`),       EXTRACT(YEAR FROM `article`.`pub_date`)
 ORDER BY `year` ASC, `month` ASC


猜你在找的Django相关文章