Navicat 17 不支持监控递归CTE执行计划资源开销,无法捕获中间迭代、每层行数或递归深度;其可视化解释器仅显示顶层文本计划,不解析JSON格式的递归节点字段,需手动在SQL编辑器中执行EXPLAIN FORMAT=JSON等语句。

Navicat 17 不支持直接监控 CTE 递归查询的执行计划资源开销
它无法捕获递归 CTE 的中间迭代步骤、每层扫描行数或递归深度消耗,EXPLAIN 结果只显示顶层计划框架,不展开 WITH RECURSIVE 内部的 repeated scan 或 materialization 行为。MySQL 8.0+ 和 PostgreSQL 的 EXPLAIN FORMAT=JSON 才包含递归节点的 recursion_depth、rows_examined_per_loop 等字段,而 Navicat 17 的可视化解释器默认走传统文本格式,且不解析 JSON 输出。
手动触发带资源标记的 EXPLAIN 是唯一可行入口
必须绕过 Navicat 的“解释”按钮,改用 SQL 编辑器直连执行带格式和提示的语句:
- 对 MySQL:运行
EXPLAIN FORMAT=JSON WITH RECURSIVE t AS (SELECT 1 n UNION ALL SELECT n+1 FROM t WHERE n ,然后手动复制 JSON 结果到外部工具解析 - 对 PostgreSQL:运行
EXPLAIN (ANALYZE, BUFFERS, FORMAT JSON) WITH RECURSIVE t(n) AS (SELECT 1 UNION ALL SELECT n+1 FROM t WHERE n ,重点看Buffers和Planning Time字段 - Navicat 的“固定查询结果”按钮对执行计划表格无效——它只固定最终
SELECT返回的数据集,不保留上面EXPLAIN的输出表格 - 导出前务必确认当前标签页显示的是刚执行完的
EXPLAIN结果,而非之前缓存的任意计划;右上角导出图标仅作用于当前可见表格
CTE 递归的真实开销藏在数据库侧运行时指标里
执行计划快照本身不反映内存占用、临时表膨胀或锁等待,这些必须从数据库内部查:
- MySQL:在另一会话中查
performance_schema.events_statements_history_long,过滤digest_text含WITH RECURSIVE,看timer_wait和lock_time - PostgreSQL:执行递归查询时,立即查
pg_stat_activity找到对应pid,再关联pg_stat_statements查total_plan_time和shared_blks_read - 注意递归终止条件失效会导致无限循环——Navicat 不会主动中断,日志窗口只会卡在
Executing...,此时需手动KILL QUERY或重启连接 - 若递归深度超 1000 层(MySQL 默认限制),错误是
ERROR 1652 (HY000): Recursive query aborted after 1001 iterations,但 Navicat 可能只报“查询失败”,不透出具体 code
别依赖 Navicat 的图形化解释做递归优化判断
它把递归 CTE 渲染成单个 Materialize 或 CTE Scan 节点,掩盖了实际执行中反复回表、重复计算、临时空间申请等关键瓶颈。真正要调优,得结合:
- 数据库原生命令:MySQL 的
SHOW PROFILE FOR QUERY N(需提前SET profiling = 1) - 系统视图:PostgreSQL 的
pg_stat_progress_recursive(v14+)可实时看到当前递归层数和已处理行数 - 物理监控:观察
tmp_table_size/work_mem是否被撑满,这类参数直接影响递归中间结果能否落盘
Navicat 17 的执行计划界面是个查看器,不是分析器;对递归类查询,它的价值仅限于确认语法是否被识别为 CTE,其余全靠你手握数据库权限去挖。











