拓冰建站拓冰建站
首页 / 资讯中心 / 正文

DBeaver 执行计划实战手册:4 步定位并压快你的慢 SQL

DBeaver 执行计划实战手册:4 步定位并压快你的慢 SQL【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver一条两表 JOIN 跑 5.2 秒,SQL 一个字符没改,调了两个索引之后变成 0.3 秒。差别不在猜索引,而在于动手之前先看了一眼数据库到底打算怎么跑这条语句。数据库执行 SQL 前会先画一张施工图纸:读表的顺序、走不走索引、连接用什么算法——这张图纸就是执行计划(Execution Plan)。DBeaver 能把它渲染成一棵可视化的树,本文按生成 → 读图 → 排病灶 → 换库差异的排障顺序,带你走完整个流程。文中引用的源码路径均可在仓库中直接打开对照,例如 SQLEditorHandlerExecute.java。第一步:拿到查询的执行计划的三种方式前提:SQL 编辑器(SQL Editor)里已连上目标数据库,光标停在要排查的语句上。点工具栏带小树图标的按钮(不同语言版本标签显示为解释计划或 Explain Plan)按快捷键CTRLSHIFTE不放心可视化结果,就在编辑器里手动敲一条EXPLAIN 你的语句,直接拿原始文本注意ALTX是运行整个脚本,不是 explain,两个键位很容易记混——快捷键映射定义在 org.jkiss.dbeaver.ui.editors.sql/plugin.xml 的keyBinding段里,可以自己去翻。命令下发后,DBeaver 把语句交给数据源对应的计划解析器拿回原始数据,再由解释计划视图渲染成树。分发入口在 SQLEditorHandlerExecute.java 的CMD_EXPLAIN_PLAN分支,最终调到SQLEditor.explainQueryPlan();生成失败时状态栏直接抛出Cant explain plan for command这个错误串(见 SQLEditor.java)。 第二步:读懂树形计划,先盯住三件事树从根节点往下展开,子节点是父节点派出去干的活。读法一句话:自上而下,先看谁扫表,再看怎么连。节点在干什么:五类活扫描节点(Scan):数据怎么读出来的——全表扫还是走索引。整棵计划里最重要的节点连接节点(Join):两张表怎么合——嵌套循环(Nested Loop)、哈希连接(Hash Join)等聚合节点(Aggregate):GROUP BY、DISTINCT排序节点(Sort):ORDER BY,哈希连接内部有时也会挂一个子查询节点(Subquery):挂在外层查询下的独立计划MySQL 的 JSON 计划键名和这些节点类型一一对应:nested_loop、table、ordering_operation、grouping_operation、duplicates_removal,解析逻辑在 MySQLPlanJSON.java 里能逐行对上。每个节点看四个指标指标含义亮红灯的信号预估行数优化器认为该节点要处理多少行根节点预估和实际结果集差距悬殊成本(Cost)优化器估算的执行开销某子树成本占总成本大头访问方式表读没读走索引大表显示全表扫描连接算法JOIN 的实现方式嵌套循环连接两个大表且连接列无索引计划里的数字都是优化器的估算,不是实测值。PostgreSQL 用ANALYZE跑一遍才有实际行数与耗时;计划数据里时长单位固定是 ms,这层约定写在 AbstractExecutionPlan.java 里。第三步:常见病灶对照表,从全表扫到连接顺序日常最值钱的就是这一步。看到执行计划里有下面这些症状,先对照着查,别急着动手。出现全表扫描时看 WHERE 条件对应的列有没有索引;有索引却没用,说明优化器觉得走索引不划算(典型是过滤后仍剩大比例行)这时先想清楚索引列的顺序再建索引,原则:等值条件在前,范围条件在后SELECT p.name, SUM(oi.amount) AS total FROM products p JOIN order_items oi ON oi.product_id p.id WHERE oi.created_at 2024-01-01 GROUP BY p.name;对上面这条,created_at的范围过滤和product_id的连接列都值得进索引,一个order_items(created_at, product_id)可以同时喂饱过滤和连接连接顺序不对时看连接节点里哪张表在内侧:被反复驱动的一方,过滤后行数应该越少越好嵌套循环连着两个大表,先查连接列有没有索引;有索引还选嵌套循环,多半是统计信息过期,优化器把行数估歪了——先刷新统计再谈别的改完索引后必须重新 explain 一遍,确认计划真变了(访问方式换了、预估行数降了),而不是感觉快了第四步:MySQL、PostgreSQL、OceanBase,三种计划格式同一条 EXPLAIN,不同库吐出来的东西完全不同,DBeaver 给每家写了专用解析器。知道差异,才不会把 A 库的读法套到 B 库上。MySQL:JSON 格式计划MySQL 走EXPLAIN FORMATJSON返回计划,DBeaver 用 Gson 把 JSON 反序列化建树,顶层从query_block开始。有个细节值得知道:如果 JSON 里带message字段(比如语句本身有错),解析器会直接抛异常,视图里什么都画不出来——这不是渲染 bug,是解析器故意的。PostgreSQL:文本计划 ANALYZE 实测值PostgreSQL 返回缩进文本计划,由 PostgreExecutionPlan.java 逐行解析。它和 MySQL 最大的差异是:EXPLAIN 加ANALYZE会真的把语句执行一遍,返回实际行数与实际耗时,排查慢查询时这是最接近事实的口径。其他库同理各有专属解析器,例如 OceanBase 的 JSON 计划 OceanbasePlanJSON.java,Oracle、DB2、H2 各自一套,统一挂在 org.jkiss.dbeaver.model/src/org/jkiss/dbeaver/model/impl/plan/ 的抽象基类下。⚠️ Explain 失败:三种高概率情况上面那个 Cant explain plan 错误弹出来的时候,按概率从高到低排查:语句本身跑不通:语法错误、引用了不存在的表——先用普通执行验证一遍语句权限不够:当前账号对目标对象无权限,或库不允许该账号执行 EXPLAIN。切一个高权限账号拿到计划再交回去,是最快的路子语句类型不支持:DDL、INSERT...SELECT 这类语句并非所有库都能 explain✅ 慢 SQL 排查清单:改索引前后照单走一遍优化没结束,直到你过完这份清单:复现慢:记下改前耗时与结果集行数生成计划,根节点预估行数与实际结果集对得上;对不上就先刷统计(ANALYZE)逐个扫表节点:大表是否都走了索引扫描逐个连接节点:连接列是否有索引,嵌套循环内侧行数是否足够少加完索引重新 explain,确认计划真的变了,而不是凭手感再测耗时;仍慢就回到计划,找下一个成本最高的节点延伸阅读:解释计划视图的树渲染逻辑在 ExplainPlanViewer.java,各库计划解析器的实现都在对应驱动插件的model/plan/目录下,想深入某一家可以直接翻源码。【免费下载链接】dbeaverFree universal database tool and SQL client项目地址: https://gitcode.com/GitHub_Trending/db/dbeaver创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门