postgresqlのprepare探索の一つ


os:centos 7.4 postgresql:10.4
PREPARE:oracleのバインド変数と同様に、実行のために文を用意します.同じ実行計画を直接使用することができ、ハード解析の代価はありません.
適用シーンは、1つのセッションで類似文を大量に実行する場合、予備文が最大のパフォーマンスを発揮する可能性があります.文が複雑な場合(計画や書き換えが困難な場合)、たとえばクエリが多くのテーブルの接続に関連している場合、または複数のルールの適用が要求されている場合、パフォーマンスの違いは特に顕著になります.文が比較的計画および書き換えが容易であるが、実行にかかるコストが比較的大きい場合、予備文のパフォーマンスの利点はそれほど顕著ではありません.

prepareを使用しない

$ psql
psql (10.4)
Type "help" for help.

postgres=# create table test01(id integer, val text); 
CREATE TABLE
postgres=# \timing
Timing is on.
postgres=# DO LANGUAGE plpgsql $$ 
DECLARE 
   v_c record;
BEGIN
   for v_c in 
      select id
	    from generate_series(1,500000) as id
   loop
      execute 'insert into test01 values('||v_c.id||',repeat( chr(int4(random()*26)+65),1000))';
   end loop;
end;
$$;

DO
Time: 28109.551 ms (00:28.110)


prepareの使用

$ psql
psql (10.4)
Type "help" for help.

postgres=# drop table test01;
DROP TABLE
postgres=# create table test01(id integer, val text); 
CREATE TABLE
postgres=# \timing
Timing is on.
postgres=# DO LANGUAGE plpgsql $$ 
DECLARE 
   v_c record;
BEGIN
   deallocate prepare insert_test01_plan;
   execute 'prepare insert_test01_plan as insert into test01 VALUES($1, $2)';
   for v_c in 
      select id
	    from generate_series(1,500000) as id
   loop
      execute 'execute insert_test01_plan('||v_c.id||',repeat( chr(int4(random()*26)+65),1000)) ';
   end loop;
end;
$$;

DO
Time: 27015.875 ms (00:27.016)


1、Prepared文はセッションのライフサイクル全体にのみ存在し、セッションが終了するとPrepared文も存在しません.次回使用する場合は再作成する必要があります.2、Prepared文は複数の同時クライアントで共有できません.3、prepared文はDEALLOCATEコマンドでクリアできます.4、現在のセッションのprepared文:pg_prepared_statements
何事にも両面性があり、prepareは性能を高めると同時に、性能の殺し屋になる可能性もある.
参照先:http://postgres.cn/docs/10/sql-prepare.html#SQL-PREPARE-EXAMPLES