ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

PostgreSQL 中 EXPLAIN 与 EXPLAIN ANALYZE 的区别:一个会执行查询,一个不会

PostgreSQL 中 EXPLAIN 与 EXPLAIN ANALYZE 的区别:一个会执行查询,一个不会 文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载EXPLAIN是 PostgreSQL 中探查查询执行计划与性能表现的核心命令而EXPLAIN ANALYZE常被当作它的加强版在对话中混用。本篇基于 til 仓库中 postgres/difference-between-explain-and-explain-analyze.md 的实战记录厘清两者的本质差异——EXPLAIN ANALYZE会真正执行查询EXPLAIN不会并围绕 INSERT/UPDATE/DELETE 等写操作给出可复现的验证示例帮助你安全、正确地用它们定位查询瓶颈。核心区别执行与不执行EXPLAIN语句可以让你对一条查询的性能表现获得洞察。日常交流中EXPLAIN和EXPLAIN ANALYZE经常被混着叫但它们都能用来探查查询如何执行的同时有一个关键区别必须清楚EXPLAIN ANALYZE会执行查询EXPLAIN不会执行查询。对于SELECT查询这个区别可能感觉并不重要——毕竟 SELECT 本身没有副作用。但对于INSERT、UPDATE和DELETE这类写语句你就必须搞清楚自己用的是哪一个了因为两者的数据影响完全不同。仅输出成本估算EXPLAINEXPLAIN只输出规划器基于统计信息生成的成本估算cost estimates不触碰真实数据。下面针对books表执行一条 INSERT 的 EXPLAIN explain insert into books (title, author) values (Fledgling, Octavia Butler); QUERY PLAN ---------------------------------------------------- Insert on books (cost0.00..0.01 rows1 width76) - Result (cost0.00..0.01 rows1 width76) select count(*) from books; count ------- 0可以看到执行完EXPLAIN insert ...之后再次select count(*)books表依然是0 行——查询并没有真正执行你得到的只是这条 INSERT 语句的成本估算值。cost0.00..0.01中的起始成本与总成本、rows1的估算行数、width76的估算元组宽度全部来自规划器的代价模型与表统计信息。输出实际执行数据EXPLAIN ANALYZEEXPLAIN ANALYZE会真实执行这条 INSERT并输出成本估算 实际执行数据actual numbers explain analyze insert into books (title, author) values (Fledgling, Octavia Butler); QUERY PLAN ---------------------------------------------------------------------------------------------- Insert on books (cost0.00..0.01 rows1 width76) (actual time0.285..0.285 rows0 loops1) - Result (cost0.00..0.01 rows1 width76) (actual time0.012..0.012 rows1 loops1) Planning time: 0.021 ms Execution time: 0.309 ms select count(*) from books; count ------- 1对照两次输出可以看到三组关键差异多出actual time/rows/loops字段每个计划节点都附带了真实耗时单位毫秒、实际行数与循环次数多出Planning time与Execution time两行分别对应规划阶段与实际执行阶段的耗时副作用确实发生执行完EXPLAIN ANALYZE insert ...之后books表中真实多出了一行count 从 0 变为 1。也就是说EXPLAIN ANALYZE给你的是预测 实测的完整画像但代价是它会像正常执行语句一样修改数据。同理EXPLAIN ANALYZE用在UPDATE、DELETE上也会真实改动或删除数据必须谨慎。什么时候用哪一个基于上述差异可以给出明确的选用原则场景推荐命令原因只读查询SELECT调优EXPLAIN ANALYZE无副作用且能拿到实际耗时与行数判断是否与估算严重偏离写操作INSERT/UPDATE/DELETE排查先用EXPLAIN只读执行计划不产生任何数据改动需要验证写操作的真实代价EXPLAIN ANALYZE配合事务回滚确认实际耗时但要接受数据会被修改对于写操作如果想安全地获得真实执行数据一个常用技巧是把EXPLAIN ANALYZE放在事务中执行并回滚begin; explain analyze delete from books where title Fledgling; rollback;这样既能拿到真实执行指标又不会让数据被永久改动注意即便回滚语句仍会真实执行、占用锁与资源行为与正常 DML 一致。从仓库延伸EXPLAIN 的实战配套用法这条 TIL 记录是 til 仓库 PostgreSQL 分类下查询性能探查系列的一部分仓库内还有若干与之直接配套的实战笔记组合使用可以覆盖从看懂计划到量化对比的完整链路。多种输出格式TEXT / JSON / YAML / XMLEXPLAIN或EXPLAIN ANALYZE默认输出为供人阅读的TEXT格式。在 postgres/output-explain-query-plan-in-different-formats.md 中展示了如何切换到程序可解析的标准化格式例如 explain (analyze, format json) select title from books where created_at now() - 1 year::interval; QUERY PLAN ---------------------------------------------------------------- [ { Plan: { Node Type: Seq Scan, Parallel Aware: false, Async Capable: false, Relation Name: books, Alias: books, Startup Cost: 0.00, Total Cost: 1.28, Plan Rows: 5, Plan Width: 32, Actual Startup Time: 0.008, Actual Total Time: 0.014, Actual Rows: 22, Actual Loops: 1, Filter: (created_at (now() - 1 year::interval)), Rows Removed by Filter: 0 }, Planning Time: 0.050, Triggers: [ ], Execution Time: 0.023 } ] (1 row)explain (analyze, format json)中的format选项可取值TEXT默认、JSON、YAML、XML适合接入监控、自动化分析或生成可视化工具。用 EXPLAIN ANALYZE 做量化性能对比仓库中的 postgres/lower-is-faster-than-ilike.md 展示了EXPLAIN ANALYZE的另一典型用法——量化对比两种写法的真实耗时。该记录通过对比select * from users where email ilike some-emailexample.com;与select * from users where lower(email) lower(some-emailexample.com);发现lower()写法耗时约 12msilike写法约 17ms而为lower(email)建立函数索引create unique index users_unique_lower_email_idx on users (lower(email));之后lower()写法骤降至约 0.08ms。这正是EXPLAIN ANALYZE的价值所在它提供的实际执行时间让不同实现方案的优劣一目了然也验证了索引是否被真正利用。在应用层Rails调用 EXPLAINPostgreSQL 之外应用框架也常把EXPLAIN暴露给开发者。仓库 rails/perform-sql-explain-with-activerecord.md 记录了在 Pry 会话中通过 ActiveRecord 对任意ActiveRecord::Relation直接调用#explainRecipe.all.joins(:ingredient_amounts).explain Recipe Load (0.9ms) SELECT recipes.* FROM recipes INNER JOIN ingredient_amounts ON ingredient_amounts.recipe_id recipes.id EXPLAIN for: SELECT recipes.* FROM recipes INNER JOIN ingredient_amounts ON ingredient_amounts.recipe_id recipes.id QUERY PLAN ---------------------------------------------------------------------------- Hash Join (cost1.09..26.43 rows22 width148) Hash Cond: (ingredient_amounts.recipe_id recipes.id) - Seq Scan on ingredient_amounts (cost0.00..21.00 rows1100 width4) - Hash (cost1.04..1.04 rows4 width148) - Seq Scan on recipes (cost0.00..1.04 rows4 width148) (5 rows)注意 ActiveRecord 的#explain只产生成本估算等价于EXPLAIN不会执行查询这与本文强调的核心区别一致——在 ORM 层面默认就选择了无副作用的版本。配合 psql 工具\timing与statement_timeout探查性能时还可以借助 psql 与 PostgreSQL 自身的配套设施仓库 postgres/turn-timing-on.md 记录在psql中执行\timing可以开关每条查询的耗时显示毫秒级适合在平时随手观察查询速度仓库 postgres/prevent-a-query-from-running-too-long.md 记录通过set statement_timeout to 500;或带单位如15s为当前连接设置语句超时避免调优过程中一条失控的EXPLAIN ANALYZE长时间占用资源。小结EXPLAIN与EXPLAIN ANALYZE唯一的本质区别就是是否真实执行查询前者只输出规划器的成本估算后者会真实执行并附上实际耗时、行数等实测数据。对 SELECT 而言选哪个问题不大对 INSERT、UPDATE、DELETE 等写语句务必先想清楚——你只是想看执行计划用EXPLAIN还是愿意接受数据被真实改动用EXPLAIN ANALYZE。配合事务回滚、JSON/YAML/XML 格式输出、\timing与statement_timeout你就能在安全的前提下获得最准确的执行画像。赞分享文档教程知识库【免费下载链接】til:memo: Today I Learned项目地址https://gitcode.com/gh_mirrors/ti/til点击查看免费下载相关推荐TDengine 查询执行计划分析实战使用 EXPLAIN 与 EXPLAIN ANALYZE 定位慢查询瓶颈TDengine 查询执行计划分析实战使用 EXPLAIN 与 EXPLAIN ANALYZE 定位慢查询瓶颈 TDengine 的 EXPLAIN / EX数据库时序数据库物联网大数据实时分析云原生终极指南7分钟掌握VisionAgent视觉AI代码生成的核心技术终极指南7分钟掌握VisionAgent视觉AI代码生成的核心技术 VisionAgent作为LandingAI推出的革命性视觉AI助手通过智能代码生成技术人工智能AI Agent代码智能体计算机视觉AI 应用Java Programming Tutorial for Beginners函数式编程基础与Lambda表达式Java Programming Tutorial for Beginners函数式编程基础与Lambda表达式 Java函数式编程是现代Java开发中的重要创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表