以下是explain.depesz.com的示例计划:
Limit (cost=65301.950..65301.950 rows=1 width=219) (actual time=886.074..886.074 rows=0 loops=1)
-> Sort (cost=65258.840..65301.950 rows=17243 width=219) (actual time=879.683..885.211 rows=17589 loops=1)
Sort Key: juliet.romeo
Sort Method: external merge Disk: 4664kB
-> Hash Join (cost=30177.210..62214.980 rows=17243 width=219) (actual time=278.986..852.834 rows=17589 loops=1)
Hash Cond: (whiskey_quebec.whiskey_five = juliet.quebec)
-> Bitmap Heap Scan on whiskey_quebec (cost=326.060..21967.630 rows=17243 width=4) (actual time=7.494..65.956 rows=17589 loops=1)
Recheck Cond: (golf = 297)
-> Bitmap Index Scan on kilo (cost=0.000..321.750 rows=17243 width=0) (actual time=4.638..4.638 rows=17589 loops=1)
Index Cond: (golf = 297)
-> Hash (cost=15750.510..15750.510 rows=329651 width=219) (actual time=267.388..267.388 rows=329651 loops=1)
Buckets: 1024 Batches: 128 Memory Usage: 679kB
-> Seq Scan on juliet (cost=0.000..15750.510 rows=329651 width=219) (actual time=0.003..65.704 rows=329651 loops=1)
这些操作的执行顺序是什么?自下而上?自上而下?
答案 0 :(得分:6)
两个方向都有道理。从上到下请求数据。从下到上的数据。你看到一棵树 - 每个节点都有一个孩子。在执行时,节点调用他的孩子 - “发送数据”,这个调用被递归地重复到叶子 - seq扫描,索引扫描,设置返回的函数调用,...产生数据和逐行 - 是发送给父母的数据。
答案 1 :(得分:0)
我通常开始从{strong>底部最后一行->
到顶部阅读树。
对于您来说,它显然需要数据才能对其进行排序,因此排序是它要做的最后一件事...
顺序扫描和索引查找:
要查找的重要内容通常是是否使用索引。
如果您没有足够的数据供计划者使用索引,则可以使用SET enable_seqscan = OFF;
disable sequential scan来强制使用索引。
记得放回去!
重要:如果您使用EXPLAIN ANALYZE(或ANALYZE),则会产生副作用!!!
我真的建议您阅读official docs,还可以找到一些不错的东西,例如将输出作为yaml或json:
EXPLAIN (format yaml) your_query_here