Django ORM和SQL 优化

影响数据库性能的因素很多,比如服务器硬件,磁盘IO速度,网卡流量,SQL查询语句。

本文只关注当Django项目使用到ORM时,如何优化?

一. 设置数据库持久连接CONN_MAX_AGE

  根据压测结果来配置。

CONN_MAX_AGE, 用来配置 Django 跟数据库的持久化连接。
从使用上来说,它可以理解为其他语言框架中数据库连接池的概念,但从实现
上来看它并不是。这一项配置的默认值是0.
Django中数据库连接的逻辑是,每一个请求结束,
都会关闭当前的数据库连接。这意味着每来一个新的请求,Django都会创建一个新的数据库连接。

配置此项的值时,需要根据参考数据库的wait_timeout 配置,建议不要大于wait_timeout
的值。此外,可选项还有None.如果配置为None, 就意味着不限制连接时长。
初步接触 Django并且上线项目时,可能对这一项配置没有太多了解。很多人在第一次部署
Django 项目之后,访问量稍微大一点时,就很容易遇到一个问题:
数据库层抛出 too many connections 错误。
其原因就是上面所说的:默认情况下,每个请求都会去创建一个新连接,
请求结束时会关掉这个连接。所以当并发访问量过大来不及关闭连接时,会导致连接数不断增多。
但是需要注意的是,如果你采用多线程的方式部署项目,那么最好不要配置 CONN_MAX_AGE.
因为如果每一个请求都会使用一个新的线程来处理的话,那么每个持久化的连接就达不到复用的
目的。另外一个经验就是,如果使用 gevent 作为 worker 来运行项目的话,那么也建议不配置
CONN_MAX_AGE.因为gevent会给 Python的 thread (线程模块)动态打补丁(patch) , 这会导致
数据库连接无法复用。
等最后我们部署完项目之后,读者可以进行压力测试来体验。
配置好MySQL并添加内容后,我们可以再次通过django-debug-toolbar和silk 来排查性能问
题,并进行优化。

   ————《Django企业开发实战》P276

二. 合理的创建索引

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

1. 频繁出现在where条件子句的字段

如get, filter,不过一般get中的字段是主键和唯一键,也就不需要建索引,filter中bool型或使用了choice的字段也不需要建立索引(因为会较频繁修改)

2. 经常被用来分组(group by) 或排序(order_by) 的字段

排序比较频繁的比如created_at字段
3. 用于联接的列(主健/外健)上建立索引
4, 在经常存取的多个列上建立复合索引,但要注意复合索引的建立顺序委按照使用的频度来确定

如联合唯一索引

三. 减少SQL语句的执行次数

提示:使用debug_tool_bar 查看效果

1.对于涉及到外键的,使用select_related,prefetch_related

四. 仅获取需要的字段数据

使用defer,only

五. 使用批量创建,更新和删除,不随意对结果排序

 如模型类中不轻易使用ordering字段排序

 
原文地址:https://www.cnblogs.com/jeff-ideas/p/10540325.html