Django 数据库 ENGINE 完全指南:选错了,性能差 10 倍

你在 settings.py 里写的那行 ENGINE,决定了 Django 怎么跟数据库说话。选错了,轻则报错,重则拖垮整个服务。


一、ENGINE 到底是什么?

DATABASES 配置里的 ENGINE,本质上是一个 Python 模块路径,指向 Django 的数据库后端实现。

python 复制代码
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',  # ← 就这一行,决定了一切
        'NAME': 'mydb',
        ...
    }
}

Django 启动时,会根据这个路径 import 对应的模块,然后用它来:

  • 建立连接
  • 发送 SQL
  • 处理事务
  • 管理连接生命周期

不同的 ENGINE = 不同的驱动 + 不同的连接策略 + 不同的性能表现。


二、MySQL 的三种 ENGINE,差别巨大

这是最容易踩坑的地方。MySQL 光 ENGINE 就有三种可选:

ENGINE 底层驱动 连接池 性能 推荐度
django.db.backends.mysql mysqlclient(C 扩展) ❌ 无 ⭐⭐⭐⭐⭐ 开发 / 低并发
dj_db_conn_pool.backends.mysql mysqlclient + DBUtils ✅ 有 ⭐⭐⭐⭐⭐ 生产首选
mysql.connector.django mysql-connector-python(纯 Python) ❌ 无 ⭐⭐⭐ 兼容优先

2.1 django.db.backends.mysql --- Django 亲生的

Django 自带,不用装任何额外包。

底层用的是 mysqlclient,这是一个 C 扩展,性能最好。

但它没有连接池。

每次请求来了,开连接 → 查数据 → 关连接。请求走了,连接就断了。

复制代码
请求1 → 开连接 → 查询 → 关连接
请求2 → 开连接 → 查询 → 关连接
请求3 → 开连接 → 查询 → 关连接

QPS 低的时候没问题。QPS 一上来,光是建连接的开销就能把 MySQL 拖慢。

⚠️ 你配置里写了 POOL_OPTIONS,但这个 ENGINE 完全不认识,等于白写。


2.2 dj_db_conn_pool.backends.mysql --- 带连接池的

第三方包 dj-database-url 生态里的 dj-db-conn-pool

底层还是 mysqlclient,但外面包了一层 DBUtils.PersistentDB 连接池。

复制代码
请求1 → 从池里拿连接 → 查询 → 还回池里
请求2 → 从池里拿连接 → 查询 → 还回池里
请求3 → 从池里拿连接 → 查询 → 还回池里

你配置里的 POOL_OPTIONS 就是给它用的:

参数 含义 你的配置 说明
POOL_SIZE 池里最多放几个连接 10 够用,别设太大
MAX_OVERFLOW 池满了还能额外创建几个 5 突发流量的缓冲
RECYCLE 连接存活多久后强制重建 3600 秒 必须 < MySQL 的 wait_timeout
TIMEOUT 池满了等多久,超时报错 30 秒 合理

生产环境用这个,你的 POOL_OPTIONS 才能真正生效。

安装:

bash 复制代码
pip install dj-database-url dj-db-conn-pool

2.3 mysql.connector.django --- MySQL 官方出的

MySQL 官方团队维护的 Django 后端。

底层用 mysql-connector-python纯 Python 实现,不依赖 C 扩展。

优点 缺点
不用装系统级 mysqlclient 性能比 mysqlclient 慢 20~30%
部署简单,pip install 就行 没有连接池
MySQL 8.0 认证插件无缝支持 社区生态不如 mysqlclient 成熟

什么时候用它?

  • 服务器装不了 mysqlclient(缺少编译环境)
  • MySQL 8.0 用了 caching_sha2_password 认证,mysqlclient 版本太老
  • Docker 镜像不想加系统依赖

三、不只是 MySQL,其他数据库的 ENGINE

数据库 ENGINE 底层驱动 备注
PostgreSQL django.db.backends.postgresql psycopg2 / psycopg3 ✅ 生产首选 psycopg3
SQLite django.db.backends.sqlite3 Python 内置 开发 / 测试用
Oracle django.db.backends.oracle cx_Oracle 企业级,配置复杂
SQL Server mssql-django pyodbc Windows 生态

PostgreSQL 特别说一下

Django 4.2+ 推荐用 psycopg3

python 复制代码
'ENGINE': 'django.db.backends.postgresql',
'OPTIONS': {
    'options': '-c search_path=public',
},

如果要连接池,PostgreSQL 的选择更多:

方案 ENGINE 说明
无池 django.db.backends.postgresql 够用
连接池 dj_db_conn_pool.backends.postgresql 和 MySQL 那个同一个包
专业级 用 PgBouncer(外部代理) 超大并发才需要

四、怎么选?一张决策表

你的场景 MySQL ENGINE PostgreSQL ENGINE
开发 / 测试 django.db.backends.mysql django.db.backends.postgresql
生产,QPS < 50 django.db.backends.mysql django.db.backends.postgresql
生产,QPS > 50 dj_db_conn_pool.backends.mysql dj_db_conn_pool.backends.postgresql
装不了 C 扩展 mysql.connector.django django.db.backends.postgresql(psycopg3 是纯 Python)
MySQL 8.0 认证报错 mysql.connector.django ---
超大并发(QPS > 1000) 外部 ProxySQL 外部 PgBouncer

五、常见坑

坑1:POOL_OPTIONS 写了但不生效

用了 django.db.backends.mysql,却写了 POOL_OPTIONS

这个 ENGINE 不认识这些参数,Django 启动不会报错,但也不会生效。 等于你精心调了一堆参数,全白费。

坑2:RECYCLE > MySQL wait_timeout

你设了 RECYCLE: 3600,但 MySQL 的 wait_timeout 默认是 28800(8 小时),看起来没问题。

但如果运维改了 MySQL 配置,wait_timeout 变成 1800(30 分钟),你的连接池还在用 3600 秒前的连接,直接报 MySQL server has gone away

铁律:RECYCLE 必须 小于 MySQL 的 wait_timeout,建议设成它的 1/2。

坑3:SQLite 用在生产

django.db.backends.sqlite3 是文件数据库,并发写会锁整个文件。

开发可以,生产别用。真要省成本,用 PostgreSQL,别用 SQLite。


六、总结

优先级 动作
1 生产环境 MySQL → 换成 dj_db_conn_pool.backends.mysql
2 你的 POOL_OPTIONS 配置是对的,但要配对 ENGINE 才生效
3 RECYCLE 查一下 MySQL 的 wait_timeout,确保 RECYCLE < wait_timeout
4 PostgreSQL 优先用 psycopg3
5 别在生产用 SQLite

那行 ENGINE,值得你花 5 分钟认真选一次。

相关推荐
兵慌码乱18 小时前
面向桌面端的资产管理系统分层架构设计与核心模块实现
python·系统架构·sqlite·pyqt5·数据库设计·桌面应用开发·mvc架构
hboot19 小时前
AI工程师第三课 - 机器学习基础
python·scikit-learn·kaggle
顾林海1 天前
Agent入门阶段-编程基础-Python:流程控制
python·agent·ai编程
呱呱复呱呱1 天前
Django CBV 源码解读:一个请求是怎么找到你的 get() 方法的
python·django
曲幽1 天前
刚部署的 LibreTranslate 频频翻车?我掏出了 20 年前的 StarDict 词典,用 FastAPI 搭了个本地词典翻译 API
python·fastapi·web·translate·goldendict·libretranslate·stardict·pystardict
荣码1 天前
用Streamlit给AI应用套个界面,10行代码出Web页面
java·python
兵慌码乱2 天前
基于Python+PyQt5+SQLite的药房管理系统实现:事务一致性与界面解耦全流程解析
python·sqlite·信号与槽·pyqt5·数据库设计·桌面应用开发·事务处理
金銀銅鐵2 天前
[Python] 体验用欧几里得算法计算最大公约数的过程
python·数学
FreakStudio2 天前
W55MH32L-EVB 上手测评:硬件 TCP/IP 加持的以太网单片机,MicroPython 零门槛开发
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
用户0332126663672 天前
使用 Python 从零创建 Word 文档
python