POSTGRESQL V12 Perpare 功能到底是个什么?

2021-05-28 00:00:00 查询 语句 执行 方式 计划


POSTGRESQL 的 prepare 的功能是什么, 有什么用,为什么在MYSQL上不曾听说有这样的功能。那么今天就需要好好的说一说POSTGRESQL 的prepare的功能。


在数据库中SQL的执行都是需要执行计划的,而每次的语句执行都是需要执行计划的参与,而随着数据量的增长以及查询条件的值的变化,可能执行计划会变化。在SQL 的执行中执行计划本身是一个变动的状态,那么PREPARE的存在的理由在哪里。 


首先我们要知道他们的不同点在哪里,有一句话表达普通的语句执行时静态的,需要进行执行计划的筛选执行起来相对较慢的并且容易受到攻击的一种语句的执行的方式。

而PERPARE的方式是动态的并且由于可以不在进行执行计划的选择,用相对较快的执行的速度,并且可以从某种角度上避免攻击的一种语句执行的方式。


Prepare 本身的功能是创建一个基于服务端的语句优化的方式,当prepare语句被执行相关的语句的解析,分析,和重写这些事情都不需要再做了。频繁且语句量大的执行可以通过这样的方式来避免做上述的工作N次。


Prepared 语句仅仅在自己的对当前的数据库的SESSION 生效,当SESSION 结束,则prepare 就失效了, Prepared 语句本身的就在于在一个SESSION中大量执行相同的语句,尤其对于比较“重”的语句,如多个表的JOIN , 这样对于这样语句频繁的运行有性能优化的作用。


下面我们通过一个练习来看看PREPARE是如何使用的


1  我们创建一个数据库 prepare

create database  prepare

2  然后我们创建一个表其中灌入数据100万的同样的数据 和 一条与其他单一的数据并建立索引,(不过大概率会有人说这个索引其实建立了白建)


但是话的分两边说, 如果查询的是那一条数据,并且是频繁的去查的情况下,那建立这个索引是有必要的。


我们通过postgresql 中的 pg_stats 中对PG的表进行查看优化情况,其中记录了表的状态。其中记录了这个表中值 hans


我们对查询进行prepare 


PREPARE myplan(text) AS
       SELECT  count(*)
       FROM    t_sample
       WHERE   name = $1;


然后分表对查询进行多次,可以看到不使用prepare的方式的查询的查询时间的波动会比较大。使用prepared 的方式比较稳定,并且时间也很短。



另外在PG 12中相关可以调整一个参数值来控制语句对于PREPARE的语句的参数值的控制方式。


SET plan_cache_mode = 'force_generic_plan';


通过上面的命令可以将PREPARE的查询的计划固定,可以看到在使用了 force_generic_plan 后, 相关的PREPARE查询会根据pg_stats中的数据的分布情况,计算出一个常用的执行计划,此时执行paul 也会使用全表扫描的方式来查询,从而查询的时间被延迟。


也可以将查询计划进行变更 通过设置为 force_custom_plan的方式让查询在根据实际的情况进行变动。



终上所述,PREPARE 查询的方式的好处在上文中已经提到

但是我们也必须去看他的反面


1  如果你的查询的值偏重性非常高,也就是你查询的值的稳定性不好的情况下,慎重PREPARE 可能不会提高查询速度,反而降低你的查询速度

2  在某些情况下会无法使用PREPARE的方式 ,例如你使用了中间件的方式并且中间件的方式中通过transaction的方式来进行变换你的查询复用,可能这样的prepare的方式的优势会被影响。



相关文章