PostgreSQL 中的EXPLAIN也可以使用 ANALYZE 选项显示语句的实际运行时间和更多信息:
EXPLAIN ANALYZESELECT e.first_name,e.last_name,e.salary,d.department_nameFROM employees eJOIN departments d ON (e.department_id = d.department_id) WHERE e.salary > 15000;QUERY PLAN|----------------------------------------------------------------------------------------------------------------|Hash Join(cost=3.38..4.84 rows=3 width=29) (actual time=0.347..0.382 rows=3 loops=1)|Hash Cond: (d.department_id = e.department_id)|->Seq Scan on departments d(cost=0.00..1.27 rows=27 width=15) (actual time=0.020..0.037 rows=27 loops=1)|->Hash(cost=3.34..3.34 rows=3 width=22) (actual time=0.291..0.292 rows=3 loops=1)|Buckets: 1024Batches: 1Memory Usage: 9kB|->Seq Scan on employees e(cost=0.00..3.34 rows=3 width=22) (actual time=0.034..0.280 rows=3 loops=1)|Filter: (salary > '15000'::numeric)|Rows Removed by Filter: 104|Planning Time: 1.053 ms|Execution Time: 0.553 ms
EXPLAIN ANALYZE通过执行语句获得了更多的信息 。其中 , actual time 是每次迭代实际花费的平均时间(ms) , 也分为启动时间和完成时间;loops 表示迭代次数;Hash 操作还会显示桶数(Buckets)、分批数量(Batches)以及占用的内存(Memory Usage) , Batches 大于 1 意味着需要使用到磁盘的临时存储;Planning Time 是生成执行计划的时间;Execution Time 是执行语句的实际时间 , 不包括 Planning Time 。
关于 PostgreSQL 的执行计划和性能优化 , 可以参考 PostgreSQL 官方文档性能提示(https://www.postgresql.org/docs/12/performance-tips.html) 。
SQLite 执行计划
SQLite 也提供了EXPLAIN QUERY PLAN命令 , 用于获取 SQL 语句的执行计划:
sqlite> EXPLAIN QUERY PLAN...> SELECT e.first_name,e.last_name,e.salary,d.department_name...>FROM employees e...>JOIN departments d ON (e.department_id = d.department_id)...>WHERE e.salary > 15000;QUERY PLAN|--SCAN TABLE employees AS e`--SEARCH TABLE departments AS d USING INTEGER PRIMARY KEY (rowid=?)
SQLite 中的EXPLAIN QUERY PLAN支持 SELECT、INSERT、UPDATE、DELETE 等语句 。
SQLite 执行计划同样按照缩进来显示 , 缩进越多的越先执行 , 同样缩进的从上至下执行 。以上示例先扫描 employees 表 , 然后针对该结果依次通过主键查找 departments 中的数据 。SQLite 只支持一种连接实现 , 也就是 nested loops join 。
另外 , SQLite 中的简单EXPLAIN也可以用于显示执行该语句的虚拟机指令序列:
sqlite> EXPLAIN...> SELECT e.first_name,e.last_name,e.salary,d.department_name...>FROM employees e...>JOIN departments d ON (e.department_id = d.department_id)...>WHERE e.salary > 15000;addropcodep1p2p3p4p5comment---------------------------------------------------------0Init015000Start at 151OpenRead0501100root=5 iDb=0; employees2OpenRead120200root=2 iDb=0; departments3Rewind0140004Column07100r[1]=employees.salary5Le2131(BINARY)53if r[1]<=r[2] goto 136Column010300r[3]=employees.department_id7SeekRowid113300intkey=r[3]8Column01400r[4]=employees.first_name9Column02500r[5]=employees.last_name10Column07600r[6]=employees.salary11Column11700r[7]=departments.department_name12ResultRow44000output=r[4..7]13Next0400114Halt0000015Transaction008001usesStmtJournal=016Integer150002000r[2]=1500017Goto01000
关于 SQLite 的执行计划和优化器相关信息 , 可以参考 SQLite 官方文档解释查询计划 。
版权声明:本文为CSDN博主「董旭阳TonyDong」的原创文章 。
推荐阅读
- 各种各样加密算法的js库,安全加密不再愁——crypto-js
- 五分钟搞定 HTTPS 配置,手把手教
- 这一次,让你完全理解 HTTPS 到底是如何做到数据传输安全的
- 车子三元催化器有多值钱?为何车商和修理厂要偷换,一次讲清楚
- 漂流常识之漂流注意事项
- 怎样修理马桶盖阻尼器,马桶盖阻尼器是一次性的吗
- 解如何利用CORS跨域,是时候让前端来指挥一次后端同学开发了
- 第一次的痛是什么样的 第一次到底有多疼痛
- 几分钟就能搞定的葱油饼,早餐的首选
- 如何选轮胎?浅显易懂,一篇搞定