开发时可通过开启 general_log(mysql)、log_statement(postgresql)或 orm 的 .query/.explain() 查看 sql;但生产环境禁用,日志需结合数据库服务端日志与执行计划综合分析。

MySQL 开发时怎么让 SQL 语句“自己说出来”
直接开 general_log,但别在生产环境试——它会把所有连接、查询、退出都记下来,磁盘和性能扛不住。开发机上可以临时打开,配合 general_log_file 指定路径,避免日志混进系统默认位置。
-
SET GLOBAL general_log = ON;启用后立刻生效(需要 SUPER 权限) -
SET GLOBAL general_log_file = '/tmp/mysql-general.log';推荐用绝对路径,否则可能写到不可见目录 - 日志是纯文本,每行一条操作,
Connect、Query、Quit都有标记,查 SQL 就盯住Query开头的行 - 关掉记得执行
SET GLOBAL general_log = OFF;,否则下次重启 MySQL 还会从配置文件里读回来(如果 my.cnf 里写了)
Django 中 debug=True 时 SQL 不显示?检查这三处
Django 的 django.db.connection.queries 只在 DEBUG=True 且请求走的是 Django 自带的开发服务器(runserver)时才累积记录;中间件顺序、数据库路由、异步视图都会让它“失灵”。
- 确认
settings.py里DEBUG = True且没被环境变量覆盖 - 别在
shell或manage.py dbshell里查connection.queries——它只对 HTTP 请求生命周期有效 - 如果用了
select_related或prefetch_related,生成的 SQL 可能比你写的 QuerySet 多几倍,注意看sql字段,别只数len(connection.queries) - 想实时看,加个简单调试:在 view 末尾 print(
connection.queries[-3:] if connection.queries else [])
PostgreSQL 怎么临时抓当前 session 的 SQL
不用改全局配置,用 log_statement 的 session 级设置最干净。它只影响当前连接,断开就自动恢复,适合调试单个 API 或脚本。
- 连上 psql 后先执行:
SET log_statement = 'all';(或'mod'只记 DML/DDL) - 日志不会返回客户端,而是输出到 PostgreSQL 的服务端日志(通常是
/var/log/postgresql/*.log),得去翻文件 - 如果用 pgAdmin 或其他 GUI 工具,它们常自带“Query Tool”里的“View Execution Plan”,勾选 “Show query details” 有时也能看到实际执行的 SQL(含参数展开)
- 注意:
log_statement = 'all'会记下SELECT,但不记绑定参数值;要看真实值,得同时设log_parameter_max_length = 1000
ORM 生成的 SQL 和你手写的不一样?先看 .explain() 和 .query
.query 属性返回的是未执行的 SQL 字符串(Django)或编译后的 Statement 对象(SQLAlchemy),它不反映最终发送给数据库的内容;真正跑起来之后,执行计划和实际参数绑定才是关键。
- Django:
print(str(MyModel.objects.filter(name__icontains='a').query))—— 这只是预编译 SQL,没带引号、没转义 - SQLAlchemy:
str(stmt.compile(compile_kwargs={"literal_binds": True}))才能看到带具体值的 SQL(仅限简单字面量,NULL 或复杂类型仍不准确) - 最靠谱的方式是结合数据库日志(上面几种)+ ORM 的
.explain()方法,它会返回数据库原生的执行计划,里面包含真实使用的索引、扫描方式、行数估算 - 特别注意:ORM 的
count()、exists()、distinct()常触发重写 SQL,别只看.query就下结论
日志不是万能的,尤其是涉及连接池、事务嵌套、预编译语句(prepared statement)时,看到的 SQL 和实际执行的可能差一层抽象。真要定位慢查询,优先抓 slow_query_log 或 pg_stat_statements,而不是依赖开发期“看起来像”的那条。











