searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Postgres执行计划初探

2024-07-31 09:49:38
5
0

语法

explain [(option[,...])] statement
EXPLAIN [ANALYZE] [VERBOSE] statement

命令的可选选项options为:

  • ANALYZE:[boolean]。通过实际执行的SQL来获得相应的执行计划。因为它真正被执行,所以可以看到执行计划每一步花掉了多少时间,以及它实际返回的行数。如果 SQL语句是一个插入、删除、更新或CREATETABLEAS语句,这些语句会修改数据库。为了不想影响实际的数据,可以把EXPLAIN ANALYZE放到一个事务中,执行完后回滚事务,如下:
BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK:
  • VERBOSE:[boolean]。用于显示计划的附加信息。这些附加信息有:计划树中每个节点输出的各个列,如果触发器被触发,还会输出触发器的名称。该选项值默认为FALSE。
  • COSTS:[boolean]。显示每个计划节点的启动成本和总成本,以及估计行数和每行宽度。该选项值默认为TRUE。
  • BUFFERS:[boolean]。显示关于缓冲区使用的信息。该参数只能与ANALYZE参数一起使用。显示的缓冲区信息包括共享块、本地块和临时块读和写的块数。共享块、本地块和临时块分别包含表和索引、临时表和临时索引,以及在排序和物化计划中使用的磁盘块。上层节点显示出来的块数包括其所有子节点使用的块数。该选项值默认为FALSE。
  • FORMAT: { TEXT | XML | JSON | YAML }。指定输出格式,输出格式可以是TEXT、XML、JSON或YAML。非文本输出包含与文本输出格式相同的信息,但其他程序更容易解析。该参数默认为TEXT。

示例

explain select from testtab01;
-- 输出
Seq Scan on testtab01 (cost=0.00..184.00 rows=10000 width=36)

Seq Scan表示顺序扫描表,也就是全表扫描。

(cost=0.00..184.00 rows=10000 width=36)可以分为三部分。

  1. cost=0.00..184.00cost后面有两个数字,中间是由..分隔,第一个数字“0.00”表示启动的成本,也就是说返回第一行需要多少cost值;第二个数字表示返回所有的数据的成本.
    • cost解释:
      • 顺序扫描一个数据块,cost值定为1。
      • 随机扫描一个数据块,cost值定为4。
      • 处理一个数据行的CPU,cost为0.01。
      • 处理一个索引行的CPU,cost为0.005。
      • 每个操作符的CPU,cost为0.0025。
  2. rows=10000:表示会返回10000行。
  3. width=36:表示每行平均宽度为36字节。

执行计划节点类型

扫描类型

全表扫描

Seq Scan表示。也称为顺序扫描(seq scan)。全表扫描就是把表的所有数据块从头到尾读一遍然后从数据块中找到符合条件的数据块。

索引扫描

Index Scan表示。索引通常是为了加快查询数据的速度而增加的。索引扫描,就是在索引中找出需要的数据行的物理位置,然后再到表的数据块中把相应的数据读出来的过程。

位图扫描

位图扫描也是走索引的一种方式。方法是扫描索引,把满足条件的行或块在内存中建一个位图,扫描完索引后,再根据位图到表的数据文件中把相应的数据读出来。如果走了两个索引,可以把两个索引形成的位图进行“and”或“or”计算,合并成一个位图,再到表的数据文件中把数据读出来。当执行计划的结果行数很多时会进行这种扫描,如非等值查询、IN子句或有多个条件都可以走不同的索引时。

Bitmap Index Scan:先在索引中找到符合条件的行;

Bitmap Heap Scan:然后在内存中建立位图之后再到表中扫描;

BitmapOr:合并成一个位图。

过滤类型

条件过滤

Filter表示。一般就是在where条件上加的过滤条件,当扫描数据行时,会找出满足过滤条件的行。

连接类型

嵌套循环连接

Nestloop Join是最朴素的表连接形式,分为内表inner table和外表outer table。内表被外表驱动,连接时会循环JOIN外表每一行在内表的对应记录。因此,外表不能太大(< 10000行),且内表的连接字段最好有有效的访问方法(索引)。

哈希连接

Hash Join适用于表较小的情况。优化器将较小的表放于内存中,通过连接键构造散列表,然后再扫描大表并探测散列表,获取与散列表匹配的行。

理想情况下,一次哈希连接总成本就是访问两个表的成本之和:一次小表散列+一次大表扫描。如果较小表不能完全放入内存,优化器会将小表切割成若干个分区,将分区放入到磁盘临时段中。因此可提高临时段容量来获取更多的IO性能。

合并连接

Merge Join适用于有索引或已排序的情况。此时合并连接性能优于哈希连接。

0条评论
0 / 1000
lljjyyhh
1文章数
0粉丝数
lljjyyhh
1 文章 | 0 粉丝
lljjyyhh
1文章数
0粉丝数
lljjyyhh
1 文章 | 0 粉丝
原创

Postgres执行计划初探

2024-07-31 09:49:38
5
0

语法

explain [(option[,...])] statement
EXPLAIN [ANALYZE] [VERBOSE] statement

命令的可选选项options为:

  • ANALYZE:[boolean]。通过实际执行的SQL来获得相应的执行计划。因为它真正被执行,所以可以看到执行计划每一步花掉了多少时间,以及它实际返回的行数。如果 SQL语句是一个插入、删除、更新或CREATETABLEAS语句,这些语句会修改数据库。为了不想影响实际的数据,可以把EXPLAIN ANALYZE放到一个事务中,执行完后回滚事务,如下:
BEGIN;
EXPLAIN ANALYZE ...;
ROLLBACK:
  • VERBOSE:[boolean]。用于显示计划的附加信息。这些附加信息有:计划树中每个节点输出的各个列,如果触发器被触发,还会输出触发器的名称。该选项值默认为FALSE。
  • COSTS:[boolean]。显示每个计划节点的启动成本和总成本,以及估计行数和每行宽度。该选项值默认为TRUE。
  • BUFFERS:[boolean]。显示关于缓冲区使用的信息。该参数只能与ANALYZE参数一起使用。显示的缓冲区信息包括共享块、本地块和临时块读和写的块数。共享块、本地块和临时块分别包含表和索引、临时表和临时索引,以及在排序和物化计划中使用的磁盘块。上层节点显示出来的块数包括其所有子节点使用的块数。该选项值默认为FALSE。
  • FORMAT: { TEXT | XML | JSON | YAML }。指定输出格式,输出格式可以是TEXT、XML、JSON或YAML。非文本输出包含与文本输出格式相同的信息,但其他程序更容易解析。该参数默认为TEXT。

示例

explain select from testtab01;
-- 输出
Seq Scan on testtab01 (cost=0.00..184.00 rows=10000 width=36)

Seq Scan表示顺序扫描表,也就是全表扫描。

(cost=0.00..184.00 rows=10000 width=36)可以分为三部分。

  1. cost=0.00..184.00cost后面有两个数字,中间是由..分隔,第一个数字“0.00”表示启动的成本,也就是说返回第一行需要多少cost值;第二个数字表示返回所有的数据的成本.
    • cost解释:
      • 顺序扫描一个数据块,cost值定为1。
      • 随机扫描一个数据块,cost值定为4。
      • 处理一个数据行的CPU,cost为0.01。
      • 处理一个索引行的CPU,cost为0.005。
      • 每个操作符的CPU,cost为0.0025。
  2. rows=10000:表示会返回10000行。
  3. width=36:表示每行平均宽度为36字节。

执行计划节点类型

扫描类型

全表扫描

Seq Scan表示。也称为顺序扫描(seq scan)。全表扫描就是把表的所有数据块从头到尾读一遍然后从数据块中找到符合条件的数据块。

索引扫描

Index Scan表示。索引通常是为了加快查询数据的速度而增加的。索引扫描,就是在索引中找出需要的数据行的物理位置,然后再到表的数据块中把相应的数据读出来的过程。

位图扫描

位图扫描也是走索引的一种方式。方法是扫描索引,把满足条件的行或块在内存中建一个位图,扫描完索引后,再根据位图到表的数据文件中把相应的数据读出来。如果走了两个索引,可以把两个索引形成的位图进行“and”或“or”计算,合并成一个位图,再到表的数据文件中把数据读出来。当执行计划的结果行数很多时会进行这种扫描,如非等值查询、IN子句或有多个条件都可以走不同的索引时。

Bitmap Index Scan:先在索引中找到符合条件的行;

Bitmap Heap Scan:然后在内存中建立位图之后再到表中扫描;

BitmapOr:合并成一个位图。

过滤类型

条件过滤

Filter表示。一般就是在where条件上加的过滤条件,当扫描数据行时,会找出满足过滤条件的行。

连接类型

嵌套循环连接

Nestloop Join是最朴素的表连接形式,分为内表inner table和外表outer table。内表被外表驱动,连接时会循环JOIN外表每一行在内表的对应记录。因此,外表不能太大(< 10000行),且内表的连接字段最好有有效的访问方法(索引)。

哈希连接

Hash Join适用于表较小的情况。优化器将较小的表放于内存中,通过连接键构造散列表,然后再扫描大表并探测散列表,获取与散列表匹配的行。

理想情况下,一次哈希连接总成本就是访问两个表的成本之和:一次小表散列+一次大表扫描。如果较小表不能完全放入内存,优化器会将小表切割成若干个分区,将分区放入到磁盘临时段中。因此可提高临时段容量来获取更多的IO性能。

合并连接

Merge Join适用于有索引或已排序的情况。此时合并连接性能优于哈希连接。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0