一次搞定各种数据库SQL执行计划( 四 )


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 msEXPLAIN 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」的原创文章 。




推荐阅读