常量和绑定变量执行计划一致
方案概述
PG awr报告中SQL
select odr.order_no, odr.order_title,server_ip,schema_name, tenant_name, file_name , odr.order_result, odr.exec_num , odr.ctime
from audit.audit_order odr, audit.test_script_svn svn
where odr.order_no = svn.dir_name and odr.order_title=$1;
PG中没有类似oracle 中dba_hist_plan, dba_hist_sqlbind. 无法知道SQL 的历史执行计划,
也不能查看SQL的绑定变量的值
EXPLAIN
select odr.order_no, odr.order_title,server_ip,schema_name, tenant_name, file_name , odr.order_result, odr.exec_num , odr.ctime
from audit.audit_order odr, audit.test_script_svn svn
where odr.order_no = svn.dir_name and odr.order_title=$1;
> ERROR: there is no parameter $1
LINE 5: and odr.order_title=$1;
> 查询时间: 0.006s
这也为我们给 SQL调优带来不便。 此时我们需要查询、评估、甚至询问开发绑定变量的值才能获取SQL的执行计划
使用PREPARE语句生成通用执行计划
prepare sql1 as
select odr.order_no, odr.order_title,server_ip,schema_name, tenant_name, file_name , odr.order_result, odr.exec_num , odr.ctime
from audit.audit_order odr, audit.test_script_svn svn
where odr.order_no = svn.dir_name
and odr.order_title=$1;
> OK
> 查询时间: 0.024s
带入测试值得到执行计划:
explain (analyse, buffers, costs ) execute sql1('供应商XXX-测XXX境-20230705-01-XXX组');
Hash Join (cost=141.31..356.46 rows=1 width=288) (actual time=7.071..7.130 rows=2 loops=1)
Hash Cond: ((svn.dir_name)::text = (odr.order_no)::text)
Buffers: shared read=251 dirtied=2
I/O Timings: read=2.435
-> Seq Scan on test_script_svn svn (cost=0.00..202.84 rows=4684 width=189) (actual time=0.085..3.832 rows=4674 loops=1)
Buffers: shared read=156 dirtied=1
I/O Timings: read=1.533
-> Hash (cost=141.30..141.30 rows=1 width=106) (actual time=2.239..2.239 rows=1 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 9kB
Buffers: shared read=95 dirtied=1
I/O Timings: read=0.902
-> Seq Scan on audit_order odr (cost=0.00..141.30 rows=1 width=106) (actual time=2.176..2.231 rows=1 loops=1)
Filter: ((order_title)::text = $1)
Rows Removed by Filter: 3701
Buffers: shared read=95 dirtied=1
I/O Timings: read=0.902
Planning Time: 0.027 ms
Execution Time: 7.251 ms
有同学会问还是需要查询、评估、甚至询问开发绑定变量的值才能获取SQL的执行计划。
有没有直接获取执行计划的方案?–答案有的,使用null 代替绑定变量但是要设置
set plan_cache_mode = force_generic_plan; 强制使用通用执行计划
pms_test=# set plan_cache_mode = force_generic_plan;
SET
pms_test=# explain (analyse, buffers, costs ) execute sql1(null);
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------
Hash Join (cost=141.31..356.46 rows=1 width=288) (actual time=2.104..2.109 rows=0 loops=1)
Hash Cond: ((svn.dir_name)::text = (odr.order_no)::text)
Buffers: shared hit=4 read=95
I/O Timings: read=0.841
-> Seq Scan on test_script_svn svn (cost=0.00..202.84 rows=4684 width=189) (actual time=0.046..0.046 rows=1 loops=1)
Buffers: shared read=1
I/O Timings: read=0.020
-> Hash (cost=141.30..141.30 rows=1 width=106) (actual time=1.952..1.953 rows=0 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 8kB
Buffers: shared hit=1 read=94
I/O Timings: read=0.820
-> Seq Scan on audit_order odr (cost=0.00..141.30 rows=1 width=106) (actual time=1.951..1.951 rows=0 loops=1)
Filter: ((order_title)::text = $1)
Rows Removed by Filter: 3702
Buffers: shared hit=1 read=94
I/O Timings: read=0.820
Planning Time: 0.741 ms
Execution Time: 2.156 ms
(18 rows)