单行注释用 #
还是 --
?关键看空格和兼容性
MySQL 支持两种单行注释语法,但行为细节有差异:
#是 MySQL 特有,
--是 SQL 标准(但 MySQL 要求其后必须跟一个空格,否则会被忽略)。
#后面直接写注释,无需空格:例如
#查询商品ID和采购价
--后**必须加空格**,否则整条语句可能报错或被截断:正确写法是
-- 查询商品ID和采购价;错误写法如
--查询商品ID和采购价在某些客户端(如老版本 mysql CLI 或部分 ORM)会触发语法错误 如果要写跨数据库兼容的 SQL(比如将来迁移到 PostgreSQL 或 SQL Server),优先用
--(带空格),避免用
#
多行注释 /* ... */
可以嵌套在语句中间,但不能嵌套自身
/* */注释最实用的地方是「插在语句中间」,比如临时屏蔽某字段、加说明,或者调试时注释掉条件片段。 支持跨行,换行符不影响解析:
SELECT product_id,
/* purchase_price, -- 暂不查采购价 */
sale_price
FROM Product;
不能嵌套:写 /* 外层 /* 内层 */ 外层 */会导致语法错误——MySQL 只认第一个
*/就结束注释,后面内容变成裸 SQL,大概率报错 可在任意位置插入,包括字段名后、逗号后、
WHERE子句中:
WHERE status = 'active' /* and deleted = 0 */
注释能放哪儿?哪些地方容易“静默失效”
理论上注释可出现在 SQL 任意位置,但实际执行中几个常见“失效点”值得警惕:
在DELIMITER改变后、存储过程体内部,某些客户端(如 phpMyAdmin)对
#注释解析不稳定,建议统一用
--或
/* */在命令行工具(
mysql -e "...")中传入含换行的
/* */注释,需确保 shell 正确转义,否则换行被截断导致注释不闭合 ORM(如 SQLAlchemy、MyBatis)可能预处理 SQL,自动剥离注释——这时你写的
--或
/* */在真正发给 MySQL 前就被删了,调试时别只信日志里看到的语句 注释里的特殊字符(如
*/出现在字符串值中)不会被识别为注释结束,安全;但若动态拼接 SQL,得防注入伪造
*/提前闭合注释
为什么注释有时“看不见效果”?其实是客户端或协议层拦截了
不是所有环境都原样把注释发给 MySQL 服务端。比如:
MySQL 8.0+ 的performance_schema.events_statements_history默认不记录注释,查慢日志或审计日志时会发现注释“消失”了 某些连接池(如 HikariCP)或代理(如 ProxySQL)会做 SQL 归一化(normalization),把注释全去掉再路由,方便缓存匹配 如果你在 Navicat / DBeaver 中写了注释却没生效,先试试切换到原生
mysqlCLI 执行——排除 GUI 工具的预处理干扰
注释看着简单,但混在复杂查询、自动化流程或多人协作脚本里时,
--少打的那个空格、
/<em></em>忘写的那个
/、或者 ORM 里以为留着的调试注释,都可能变成半夜排查的起点。
