必须同时授予select、show view和process三项权限才能执行explain,因为select仅允许读数据,show view用于展开视图定义,process用于访问线程状态以解析子查询等复杂结构。

不能只给 SELECT 权限,必须同时授予 SELECT、SHOW VIEW 和 PROCESS 三项权限,缺一不可。
为什么单独 GRANT SELECT 不够用
执行 EXPLAIN SELECT * FROM view_name; 报错 ERROR 1142 (42000): SELECT command denied 或返回空计划,不是因为缺“EXPLAIN 权限”(MySQL 根本没有这个权限),而是优化器在解析阶段卡住了:
-
SELECT权限只允许读数据,但EXPLAIN需要展开视图定义——这依赖SHOW CREATE VIEW,而它由SHOW VIEW控制 - 遇到子查询、
UNION、派生表(DERIVED)时,优化器需访问线程状态和内部上下文,必须有PROCESS权限,否则直接报ERROR 1227 (42501) - 哪怕你已能
SELECT * FROM my_view,仍可能无法EXPLAIN它——SELECT和SHOW VIEW是两个完全独立的权限,互不替代
必须授予的三个权限及其作用域
最小可行组合只有三项,但作用域不同,写错就失效:
-
SELECT ON app_db.*:必须覆盖目标库所有表,包括视图本身及其底层基表;若视图引用了other_db.t1,还得额外加SELECT ON other_db.t1 -
SHOW VIEW ON app_db.*:只能按库授予(ON app_db.*),不能写成ON app_db.my_view——MySQL 不支持对单个视图授此权限 -
PROCESS ON *.*:全局权限,无法限定到库;必须显式写ON *.*,写成ON app_db.*会静默失败
容易被忽略的元数据权限缺口
即使上述三项都给了,EXPLAIN FORMAT=JSON 仍可能缺失关键字段(比如 key、possible_keys 的判断依据),原因是优化器需要查 information_schema 表:
- 必须补上:
SELECT ON information_schema.STATISTICS(影响索引选择逻辑) - 建议加上:
SELECT ON information_schema.KEY_COLUMN_USAGE(用于推导复合索引使用长度) - 这两项权限不涉及业务数据,但缺失会导致执行计划“看起来正常”,实则关键信息残缺,误导调优判断
典型授权命令示例
以用户 '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.%'; GRANT SELECT ON information_schema.STATISTICS TO 'dev_user'@'10.0.2.%'; GRANT SELECT ON information_schema.KEY_COLUMN_USAGE TO 'dev_user'@'10.0.2.%';
执行完别忘了 FLUSH PRIVILEGES;。注意:如果用户连接时没指定默认库(如用 mysql -u dev_user -h ... 直连),EXPLAIN 对跨库视图仍可能失败——必须显式写 EXPLAIN SELECT * FROM app_db.view_name;。
最常被绕开又最致命的一点:PROCESS 权限虽不常被滥用,但它一旦授予,就无法按库隔离;而很多团队为省事直接跳过它,结果遇到含子查询的语句就卡死,却以为是 SQL 写错了。











