mysql无独立explain权限,必须组合授予select、show view和process三项权限:select用于读表与元数据,show view用于展开视图定义,process用于处理子查询等复杂结构,缺一不可。

不能只给 SELECT 权限就让 EXPLAIN 正常工作,MySQL 没有独立的 EXPLAIN 权限,它依赖多个底层权限协同生效——缺一不可,否则要么报错,要么计划不完整。
为什么只授 SELECT 权限会失败
常见错误现象是执行 EXPLAIN SELECT * FROM t1; 报 ERROR 1142 (42000): SELECT command denied,或对视图/子查询直接返回空结果。这是因为:
-
SELECT是基础,但仅够查数据;EXPLAIN需要解析 SQL 逻辑、展开视图、访问统计元数据,这些超出单纯读表范围 - 遇到视图时,必须能读取其定义(
SHOW CREATE VIEW),这由SHOW VIEW权限控制,和SELECT权限相互独立 - 涉及派生表、临时表、子查询时,优化器需查看线程状态和内部执行上下文,依赖
PROCESS权限
必须授予的三个核心权限组合
最小可行集只有三项,按作用域和必要性排列:
-
SELECTONdb_name.*:允许访问目标库中所有表和视图的数据(包括INFORMATION_SCHEMA.STATISTICS等元数据表,影响key和possible_keys字段准确性) -
SHOW VIEWONdb_name.*:必须在视图所在库级别授予,否则EXPLAIN无法展开视图定义,哪怕已有该视图的SELECT权限 -
PROCESSON*.*:全局权限,无法限定到库;缺失时对含子查询、UNION、派生表的语句会报ERROR 1227 (42501): Access denied; you need (at least one of) the PROCESS privilege(s)
示例命令(以用户 'dev_user'@'10.0.2.%' 和库 app_db 为例):
GRANT SELECT ON app_db.* TO 'dev_user'@'10.0.2.%'; GRANT SHOW VIEW ON app_db.* TO 'dev_user'@'10.0.2.%'; GRANT PROCESS ON *.* TO 'dev_user'@'10.0.2.%';
容易被忽略的权限泄露风险
授了这三项后,用户其实已能间接推断大量敏感信息:
-
EXPLAIN FORMAT=JSON会暴露索引选择依据、实际扫描行数、甚至字段长度(key_len),结合SELECT权限可反推表结构 -
SHOW VIEW允许用户执行SHOW CREATE VIEW view_name,明文看到视图 SQL,包括 WHERE 条件、JOIN 逻辑、甚至硬编码的过滤值 -
PROCESS虽不等于SHOW PROCESSLIST,但在某些 MySQL 版本下可能被用于探测活跃连接,且无法按库隔离
若业务只要求分析简单查询,可先不授 PROCESS;但一旦遇到 DERIVED 或 DEPENDENT SUBQUERY 类型,EXPLAIN 就会直接失败。
Navicat 点“解释”按钮没反应的排查重点
Navicat 的“解释”功能只是发送 EXPLAIN 语句,无额外 magic。没反应或报错,优先检查:
- 用户是否连接时指定了默认数据库(
USE app_db)?未指定且 SQL 中视图名没带库前缀,MySQL 会在当前库找,报Table doesn't exist - 视图定义里是否引用了其他库的表?用户对那些库没有
SELECT权限,EXPLAIN展开时校验失败 - 视图是否用
SQL SECURITY DEFINER创建,而DEFINER用户已失效?可用SHOW CREATE VIEW view_name验证 - MySQL 版本是否低于 5.6?旧版本不支持对 JOIN、UNION 等复杂语句的完整
EXPLAIN
真正难处理的不是权限怎么给,而是给了之后,EXPLAIN 输出本身就成了侧信道——它不删数据,但比 SELECT 更暴露设计意图和数据分布特征。











