" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper博主等级

千里之行,始于足下

  • 累计撰写 203 篇文章
  • 累计创建 14 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录
Web

Django ORM优化 和 SQL优化

PySuper
2021-02-18 / 0 评论 / 0 点赞 / 14 阅读 / 3427 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊

设置数据库持久连接

DATABASES["default"] = env.db("DATABASE_URL")
DATABASES["default"]["ATOMIC_REQUESTS"] = True

# 第一次发送请求之后,后面60s的SQL连接都不需要再连接
DATABASES["default"]["CONN_MAX_AGE"] = env.int("CONN_MAX_AGE", default=60)

合理的创建索引

索引会占用磁盘空间,创建不必要的索引只会形成浪费
主键、外键、唯一键已经建立索引

  • 频繁出现在where条件子句的字段 ==> get() filter()
    • get()请求返回的大多是一个对象,也就是查询的是主键或者唯一键,就不需要建立索引
    • filter()查询的时候,有些是布尔类型,有些是带choice的字段,也不需要
  • 经常被用来分组(greoup by)或排序(order_by)的字段 ==> db_index=True
    • 在元数据中定义的orering()
  • 用于联接的列(主键、外键)上建立索引
  • 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序要按照使用的频度来确定

减少SQL语句的执行次数

把两个SQL查询,变成一个查询语句,一次查询返回结果

主要就是 views.pymodels.py 两个文件

  • select_related():ForeignKey、OneToOneField
  • prefetch_related():ManyToManyField、GenericForeignKey(通用外键)
# 网站的所有内容要求用户登录后才能看到 ==> LoginRequiredMixin
class NewsListView(LoginRequiredMixin, ListView):
    """首页动态"""
    model = News
    paginate_by = 20  # 分页:url中的?page=
    template_name = "news/news_list.html"  # 默认: '模型类名_list.html'

    def get_queryset(self):
        """
        获取视图的对象列表, 实现动态过滤
        :return: django查询集
        """
        return News.objects.filter(reply=False)
            .select_related('user', 'parent')
                .prefetch_related('liked')


@login_required
@ajax_required
@require_http_methods(["GET"])
def get_thread(request):
    """返回动态的评论,AJAX GET请求"""
    news_id = request.GET['news']

    # 不是.get(pk=news_id).select_related('user')
    news = News.objects.select_related('user').get(pk=news_id)

    # render_to_string()表示加载模板,填充数据,返回字符串

仅获取需要的字段数据

  • 在ORM查询后面添加
    • defer():排除掉一些字段
    • only():只获取某些字段

使用批量创建、更新和删除

  • Aqw.objects.bull_create():bull_create()批量创建

不随意对结果排序

  • 没必要排序的地方,不适用ordering()
0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区