EXPLAIN失败主因是缺失SHOW VIEW、基表SELECT及information_schema读取权限,而非所谓“EXPLAIN权限”;需按数据库级授SHOW VIEW、视图级授SELECT、显式授information_schema.STATISTICS和KEY_COLUMN_USAGE,并确保默认数据库正确。

开发人员执行 EXPLAIN 失败,基本不是因为缺“EXPLAIN 权限”——MySQL 根本没有这个独立权限项;真正卡住的是 SHOW VIEW、底层表的 SELECT 权限,以及 information_schema 系统表的读取能力。
为什么 GRANT SELECT ON view_name 不够用
即使你已给开发人员授了 SELECT 权限在视图上,EXPLAIN 仍可能报错 ERROR 1142 (42000): SELECT command denied to user for table 'xxx'。这是因为 MySQL 在生成执行计划前,必须展开视图定义(即执行隐式的 SHOW CREATE VIEW),而该操作受 SHOW VIEW 权限控制。
-
SHOW VIEW必须在数据库级别授予,例如GRANT SHOW VIEW ON app_db.* TO 'dev'@'%';写成ON app_db.v_report会直接被忽略 - 若视图定义中包含跨库引用(如
SELECT * FROM log_db.events),开发人员还需有SELECT ON log_db.events,否则展开失败 - 视图若为
SQL SECURITY DEFINER且DEFINER用户已被删,SHOW CREATE VIEW自身就失败,EXPLAIN必然中断
EXPLAIN FORMAT=JSON 缺关键索引信息?补 system 表权限
默认 EXPLAIN 能显示 type、key、rows,但 FORMAT=JSON 会尝试从 information_schema.STATISTICS 和 information_schema.KEY_COLUMN_USAGE 中读取索引结构细节(比如为什么没选某个联合索引)。没权限时,JSON 输出里 used_columns、possible_keys 可能为空或不完整。
- 补授权:
GRANT SELECT ON information_schema.STATISTICS TO 'dev'@'%' - 补授权:
GRANT SELECT ON information_schema.KEY_COLUMN_USAGE TO 'dev'@'%' - 注意:MySQL 8.0+ 默认禁止对
information_schema写操作,但SELECT需显式授权才开放读取
只让开发看计划、不查基表数据的最小权限组合
目标是允许 EXPLAIN SELECT * FROM v_user_summary,但禁止 SELECT * FROM users。核心不是靠限制 EXPLAIN,而是靠权限隔离 + 视图封装。
- 建视图时严格过滤敏感字段:
CREATE VIEW v_user_summary AS SELECT id, name, role FROM users(不包含password、email) - 只授视图所在库的
SHOW VIEW:GRANT SHOW VIEW ON app_db.* TO 'dev'@'%' - 只授视图对象的
SELECT:GRANT SELECT ON app_db.v_user_summary TO 'dev'@'%' - 绝对不授基表权限:
REVOKE SELECT ON app_db.users FROM 'dev'@'%'(如有则必须收回) - 若视图 JOIN 了其他库表(如
auth_db.roles),也只授该视图对应列的SELECT,而非整个基表
最容易被忽略的一点:权限生效依赖当前默认数据库(USE db_name)。如果开发人员未指定库直接运行 EXPLAIN SELECT * FROM v_user_summary,而连接时默认库不是 app_db,MySQL 会去当前库找视图,报 Table doesn't exist——这不是权限问题,是上下文问题。建议在脚本或连接配置中显式指定 database=app_db。


















