• PostgreSQL执行计划获取与修改


    基础操作之___执行计划获取与修改

    说明:

    • explain + sql:只显示执行计划,不实际执行
    • explain analyze + sql:实际执行,并显示执行计划
    1、查询sql执行计划

    启用sql执行时间

    htdb=# \timing
    Timing is on.
    
    (1)查询执行计划(不执行)
    htdb=# explain select count(1) from httab;
                               QUERY PLAN                            
    -----------------------------------------------------------------
     Aggregate  (cost=219.00..219.01 rows=1 width=8)
       ->  Seq Scan on httab  (cost=0.00..194.00 rows=10000 width=0)
    (2 rows)
    
    Time: 8.421 ms
    
    (2)查询执行计划(实际执行)
    htdb=# explain analyze select count(1) from httab;
                                                      QUERY PLAN                                                   
    ---------------------------------------------------------------------------------------------------------------
     Aggregate  (cost=219.00..219.01 rows=1 width=8) (actual time=2.767..2.768 rows=1 loops=1)
       ->  Seq Scan on httab  (cost=0.00..194.00 rows=10000 width=0) (actual time=0.747..2.450 rows=10000 loops=1)
     Planning Time: 0.041 ms
     Execution Time: 2.790 ms
    (4 rows)
    
    Time: 3.073 ms
    

    通过用时,和统计信息两种方式,都能看出二者差别

    2、获取执行计划IO信息

    使用buffers参数显示sql执行时IO相关信息

    htdb=# explain (analyze,buffers) select count(1) from httab;
                                                      QUERY PLAN                                                   
    ---------------------------------------------------------------------------------------------------------------
     Aggregate  (cost=219.00..219.01 rows=1 width=8) (actual time=0.929..0.929 rows=1 loops=1)
       Buffers: shared hit=94
       ->  Seq Scan on httab  (cost=0.00..194.00 rows=10000 width=0) (actual time=0.006..0.553 rows=10000 loops=1)
             Buffers: shared hit=94
     Planning Time: 0.041 ms
     Execution Time: 0.945 ms
    (6 rows)
    
    Time: 1.310 ms
    htdb=# 
    

    注意:explain后跟多个选项时,需要加括号

    hit表示命中缓存,重启后缓存消失,所以变成物理读(read),如下:

    htdb=# \! pg_ctl restart -D /pgdata12
    waiting for server to shut down.... done
    server stopped
    waiting for server to start....2022-08-25 15:40:50.392 CST [10128] LOG:  starting PostgreSQL 12.3 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-36), 64-bit
    2022-08-25 15:40:50.393 CST [10128] LOG:  listening on IPv4 address "0.0.0.0", port 5432
    2022-08-25 15:40:50.393 CST [10128] LOG:  listening on IPv6 address "::", port 5432
    2022-08-25 15:40:50.393 CST [10128] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
    2022-08-25 15:40:50.404 CST [10128] LOG:  redirecting log output to logging collector process
    2022-08-25 15:40:50.404 CST [10128] HINT:  Future log output will appear in directory "log".
     done
    server started
    htdb=# \c
    You are now connected to database "htdb" as user "htuser".
    htdb=# 
    htdb=# explain (analyze,buffers) select count(1) from httab;
                                                      QUERY PLAN                                                   
    ---------------------------------------------------------------------------------------------------------------
     Aggregate  (cost=219.00..219.01 rows=1 width=8) (actual time=2.696..2.696 rows=1 loops=1)
       Buffers: shared read=94
       ->  Seq Scan on httab  (cost=0.00..194.00 rows=10000 width=0) (actual time=0.006..2.246 rows=10000 loops=1)
             Buffers: shared read=94
     Planning Time: 0.255 ms
     Execution Time: 2.739 ms
    (6 rows)
    
    Time: 3.804 ms
    htdb=#
    
    3、修改SQL执行计划

    pg中通过修改执行计划选项开关来修改执行计划

    (1)查询表(无主键索引)

    没有主键,走的全表扫描

    htdb=# explain (analyze,buffers) select * from httab where id =998;
                                                QUERY PLAN                                            
    --------------------------------------------------------------------------------------------------
     Seq Scan on httab  (cost=0.00..219.00 rows=1 width=41) (actual time=0.050..0.456 rows=1 loops=1)
       Filter: (id = 998)
       Rows Removed by Filter: 9999
       Buffers: shared hit=94
     Planning Time: 0.053 ms
     Execution Time: 0.464 ms
    (6 rows)
    
    
    (2)查询表(有主键索引)

    指定索引列条件,执行计划走index scan

    htdb=# ALTER TABLE httab ADD CONSTRAINT httab_pkey PRIMARY KEY (id); 
    ALTER TABLE
    
    htdb=#  explain (analyze,buffers) select * from httab where id =998;
                                                        QUERY PLAN                                                     
    -------------------------------------------------------------------------------------------------------------------
     Index Scan using httab_pkey on httab  (cost=0.29..8.30 rows=1 width=41) (actual time=0.445..0.447 rows=1 loops=1)
       Index Cond: (id = 998)
       Buffers: shared hit=1 read=2
     Planning Time: 0.824 ms
     Execution Time: 0.461 ms
    (5 rows)
    
    Time: 1.623 ms
    htdb=#
    
    (3)enable_indexscan参数

    禁用enable_indexscan后,查询走bitmap heap scan

    htdb=# set enable_indexscan = off;
    SET
    htdb=# explain (analyze,buffers) select * from httab where id =998;
                                                        QUERY PLAN                                                     
    -------------------------------------------------------------------------------------------------------------------
     Bitmap Heap Scan on httab  (cost=4.29..8.31 rows=1 width=41) (actual time=0.009..0.010 rows=1 loops=1)
       Recheck Cond: (id = 998)
       Heap Blocks: exact=1
       Buffers: shared hit=1 read=2
       ->  Bitmap Index Scan on httab_pkey  (cost=0.00..4.29 rows=1 width=0) (actual time=0.007..0.007 rows=1 loops=1)
             Index Cond: (id = 998)
             Buffers: shared read=2
     Planning Time: 0.164 ms
     Execution Time: 0.021 ms
    (9 rows)
    
    htdb=# 
    
    (4)enable_bitmapscan参数

    禁用enable_bitmapscan后,查询再次走全表扫描

    htdb=# explain (analyze,buffers) select * from httab where id =998;
                                                QUERY PLAN                                            
    --------------------------------------------------------------------------------------------------
     Seq Scan on httab  (cost=0.00..219.00 rows=1 width=41) (actual time=0.055..0.463 rows=1 loops=1)
       Filter: (id = 998)
       Rows Removed by Filter: 9999
       Buffers: shared hit=94
     Planning Time: 0.045 ms
     Execution Time: 0.472 ms
    (6 rows)
    

    auto_explain插件,能够把执行时间较长的SQL及执行计划写到PG日志里

    查看执行计划的网站:https://explain.depesz.com/

  • 相关阅读:
    七牛直播推流端flutter插件,支持Android和iOS
    【bug优化】Three.js 中实现圆角立方体的详尽指南
    这次把怎么做好一个PPT讲清-动画篇
    医药制药行业有机VOCs废气治理
    日常Bug排查-连接突然全部关闭
    【云原生 | Kubernetes 系列】—K8S部署RocketMQ集群(双主双从+同步模式)
    IIC协议详解
    Spring基础(3):复习
    uniapp 自定义导航栏
    Java方法调用动态绑定(多态性)详解
  • 原文地址:https://blog.csdn.net/ly7472712/article/details/127047956