利用auto_explain查看sql、procedure、function实时执行计划

文章目录

  • 1.简介
    • 1.1 实时的执行计划
    • 1.2 查看procedure、function的执行计划
  • 2.load auto_explain
  • 3.相关参数设定
  • 4.创建测试表
  • 5.测试用的function
  • 6.运行测试function
  • 7.查看执行过程
  • 8.关闭auto_explain

1.简介

postgresql中,利用explain 结合一些选项,如analyze、buffers等命令查看sql语句执行计划在一般场景下已经足够,但是基于如下原因,auto_explain将是一个强有力的补充:

1.1 实时的执行计划

鉴于pg优化器的复杂性,以及柱状图不同值数据的分布,sql不总是按照我们使用explain工具看到的执行计划执行

1.2 查看procedure、function的执行计划

对于procedure/function执行计划的分析,通常我们可以raise notice查看各个sql的时间,也可以使用explain一段一段的查看执行计划,但是在procedure/function中往往有者复杂的写法,如for loop循环,要查看这些执行情况变得相当不容易
我们今天将仅演示auto_explain的使用,细节将可以查看postgresql官方文档auto_explain

2.load auto_explain

auto_explain是一个session级的library,可以在使用时动态加载

set session_preload_libraries to auto_explain
load  'auto_explain'

3.相关参数设定

参数具体含义可参考官方文档

set auto_explain.sample_rate = 1
set auto_explain.log_min_duration = 0
set auto_explain.log_analyze = true 
set auto_explain.log_nested_statements to on

4.创建测试表

测试表t1

create table t1 (id bigint)

测试表t2

create table t2 (id bigint)
insert into t2 values(generate_series(1,10000))
create index idx_t2_id on t2(id)

5.测试用的function

create or replace function pro_test1()
returns record
LANGUAGE 'plpgsql'
as $body$
declare
v_num int :=1;
sfc record;
begin 
delete from t1;
for sfc in (select id from t2 where id >9997)
loop
insert into t1(id) select * from t2 where sfc.id=t2.id;
end loop;
return sfc;
end;
$body$;

6.运行测试function

select pro_test1()

7.查看执行过程

2023-06-27 13:53:42.728 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15056,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 0.048 ms  plan:
Query Text: delete from t1
Delete on t1  (cost=0.00..1.05 rows=5 width=6) (actual rows=0 loops=1)
  ->  Seq Scan on t1  (cost=0.00..1.05 rows=5 width=6) (actual rows=5 loops=1)",,,,,"SQL statement ""delete from t1""
PL/pgSQL function pro_test1() line 6 at SQL statement",,,,"pgAdmin 4 - CONN:3952426"
2023-06-27 13:53:42.728 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15057,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 0.019 ms  plan:
Query Text: insert into t1(id) select * from t2 where sfc.id=t2.id
Insert on t1  (cost=0.29..4.31 rows=1 width=4) (actual rows=0 loops=1)
  ->  Index Only Scan using idx_t2_id on t2  (cost=0.29..4.31 rows=1 width=4) (actual rows=1 loops=1)
        Index Cond: (id = $4)
        Heap Fetches: 0",,,,,"SQL statement ""insert into t1(id) select * from t2 where sfc.id=t2.id""
PL/pgSQL function pro_test1() line 11 at SQL statement",,,,"pgAdmin 4 - CONN:3952426"
2023-06-27 13:53:42.728 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15058,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 0.009 ms  plan:
Query Text: insert into t1(id) select * from t2 where sfc.id=t2.id
Insert on t1  (cost=0.29..4.31 rows=1 width=4) (actual rows=0 loops=1)
  ->  Index Only Scan using idx_t2_id on t2  (cost=0.29..4.31 rows=1 width=4) (actual rows=1 loops=1)
        Index Cond: (id = $4)
        Heap Fetches: 0",,,,,"SQL statement ""insert into t1(id) select * from t2 where sfc.id=t2.id""
PL/pgSQL function pro_test1() line 11 at SQL statement",,,,"pgAdmin 4 - CONN:3952426"
2023-06-27 13:53:42.728 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15059,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 0.007 ms  plan:
Query Text: insert into t1(id) select * from t2 where sfc.id=t2.id
Insert on t1  (cost=0.29..4.31 rows=1 width=4) (actual rows=0 loops=1)
  ->  Index Only Scan using idx_t2_id on t2  (cost=0.29..4.31 rows=1 width=4) (actual rows=1 loops=1)
        Index Cond: (id = $4)
        Heap Fetches: 0",,,,,"SQL statement ""insert into t1(id) select * from t2 where sfc.id=t2.id""
PL/pgSQL function pro_test1() line 11 at SQL statement",,,,"pgAdmin 4 - CONN:3952426"
2023-06-27 13:53:42.729 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15060,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 0.010 ms  plan:
Query Text: (select id from t2 where id >9997)
Index Only Scan using idx_t2_id on t2  (cost=0.29..4.34 rows=3 width=8) (actual rows=3 loops=1)
  Index Cond: (id > 9997)
  Heap Fetches: 0",,,,,"PL/pgSQL function pro_test1() line 8 at FOR over SELECT rows",,,,"pgAdmin 4 - CONN:3952426"
2023-06-27 13:53:42.729 WIB,"dbas","pccwms502Zdb",105829,"172.19.6.187:1032",649a5d9e.19d65,15061,"SELECT",2023-06-27 10:55:10 WIB,43/1567572,840415340,LOG,00000,"duration: 1.075 ms  plan:
Query Text: select pro_test1()
Result  (cost=0.00..0.26 rows=1 width=32) (actual rows=1 loops=1)",,,,,,,,,"pgAdmin 4 - CONN:3952426"

这里,可以看到输出的完整执行计划,甚至每一个for循环的执行计划都有记录下来,这对我们查看复杂sql的执行计划非常的有帮助

8.关闭auto_explain

set autoexplain.log_min_duration to -1

你可能感兴趣的:(Postgresql,sql,数据库)