执行计划个人理解是一个“点”,“线”,“面”的问题,关系数据库中执行计划是一个同质化的对象,串联起来还是比较容易掌握的,对于一条复杂的sql,所谓的点就是其中单个表的访问方式,线是表之间的连接驱动顺序,面就是表与表之间的具体连
执行计划个人理解是一个“点”,“线”,“面”的问题,关系数据库中执行计划是一个同质化的对象,串联起来还是比较容易掌握的,对于一条复杂的sql,所谓的点就是其中单个表的访问方式,线是表之间的连接驱动顺序,面就是表与表之间的具体连接算法以及中间结果在内存缓冲区中的处理(类似于bitmap scan,中间结果集的buffer处理等等),这样一来,一个sql就的执行计划就可以逐步拆解开来,可以逐个基于细节来分析。postgresql的执行计划,整体上看跟Mysql或者sqlserver都是差不多的,但Postgresql对执行计划在细节上的描述还是很粗糙的,就索引的访问形式来说:mysql中有index 遍历索引/range 索引范围查找/ref 非唯一索引查找数据/eq_ref 非唯一索引查找数据,以及回表的标记;sqlserver中也存在着scan和seek是两个完全不同的概念,以及明显的“回表”标记。在postgresql执行计划中是无法直接体现出来的,全部称之为index scan(index only scan),这一点说实话是比不上MySQL或者sqlserver的,后两者对执行计划的描述都很细化。
由于Index Only Scan表示仅需要索引就可以找到所需要的数据,无需回表,那么同样在无需回表的情况下,postgresql如何区分对索引树(b+)树的查找(真正的二分法查找)和扫描(扫描整颗B+树)?这个是一个有意思的问题,这里刻意创建一个抑制索引使用的但是无需回表的查询: select c2 from myschema.table_test where c2+1 = 1001;,
看看会发生什么,这也是笔者在一开始想不明白的一个问题,它竟然总的是走了一个全表扫描???
这里的“面”是表与表之间的连接处理方式,其实就是经典的loop join,merge join,hash join这三种join方式。
postgresql中的三种join方式与其他数据库的join在思路上并无二致,原理也很简单,基本上都有各自适合的场景和前提条件。
1.1 loop join
适合处理两个较小的结果集的场景,同时,尽管是较小的结果集,在有索引驱动的情况下loop join的效率也会相对较高,第二个图例就代表着基于索引驱动的loop join
1.2 merge join
适合处理两个有序结果集的场景,或者jion双方本身存在一致的索引键
相比loop join只有outer表会前推,merge join在join的时候,outer和inner表同时有一个“前推”的过程,也就是说随着join的进行,outer表的键对inner表的探测次数会越来越少。
要清楚,outer table和inner table的有序是merge join的因,而非果。
1.3,hash join
对于无索引且结果集较大的场景,属于重量级的查询处理。
其实平时不得见经常出现hash join,如果一个系统的查询中经常出现hash join,也不见得是一件好事,在前面两种足够“轻量级”join方式处理不动时的一种选择。
相比以上两种join方式,hash join可能较为难理解一点:hash join简单说分两个阶段,第一个阶段是构建hash桶,对join双方较小的一个表的连接键生成hash桶,第二个阶段是对join的另外一张表的键值基于hash运算后进行探测。
为什么要这么做?其实还是跟“join条件上没有索引有关”,相当于间接性地生成了一个hash索引,因此这种情况适合join双方都变较大,且没有索引的场景。
那么,为什么在重量级的join情况下为什么不加索引呢,所以上面也说了,经常看到hash join并不代表什么好现象,而是一种不得已的选择。
并行查询可以应用在绝大多数上述的点线面中
比如并行Seq Scan,并行Index Scan,并行join等等,其目的就是多个CPU协同工作,然后汇总的一种思路,这一点postgresql还是比较给力的,当然也不是并行线程数越多越好(max_parallel_workers)。
查询提示作为优化的debug作用,可以尝试强制按照非默认的执行方式来对比,参考这里:https://blog.csdn.net/jackGo73/article/details/89711523
以上截图这些有趣的图片来自于:https://momjian.us/main/writings/pgsql/internalpics.pdf
--结束END--
本文标题: Postgresql执行计划概述
本文链接: https://www.lsjlt.com/news/7576.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
2024-05-02
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0