
良い一日! PostgreSQL 9.4のリリースはそれほど遠くないので、このバージョンで導入されたいくつかの革新を経験することは有用です。 この記事では、(ほとんどの場合、クライアントモデルに関連して)以下を考慮します。
AutoUpdateビューの変更
自動更新可能な
ビューは 、
DML操作を実行できる
ビューです。 そのような提出の条件:
- FROMリスト内の1つのエンティティ(テーブルまたはビュー)のみ
- WITH 、 DISTINCT 、 GROUP BY 、 HAVING 、 LIMITおよびOFFSETステートメントの欠如
- セットUNION 、 INTERSECTおよびEXCEPTに対する操作の欠如
- 関数と演算子はフィールドに適用されません
これらのビューは、PostgreSQL 9.3で提供されていました。 バージョン9.4では、いくつかの追加が導入されています。 それらの1つは、このビューでは関数または演算子が適用されるフィールドが存在できないという事実に関連する制限を削除します(9.3では、そのようなフィールドフィールドが少なくとも1つある場合、ビューは自動更新されなくなります)。 9.4では、残りのフィールドを操作できます。 これを例で説明します。
ブックのディレクトリを作成し、その上に簡単な自動更新ビューを作成します。
CREATE TABLE book ( id serial NOT NULL, name text NOT NULL, author text NOT NULL, year integer NOT NULL, CONSTRAINT pk_book_id PRIMARY KEY ( id ), CONSTRAINT uk_book UNIQUE ( name, author ) ); INSERT INTO book ( name, author, year ) VALUES ( ' №1', ' . .', 2010 ), ( ' №2', ' . .', 2011 ), ( ' №3', ' . .', 2012 ); CREATE OR REPLACE VIEW vw_book AS SELECT b.id, b.name, b.author, b.year, ( b.year >= extract ( year FROM current_date ) - 2 ) AS is_new FROM book b;
データの更新:
自動更新の場合、
WITH CHECK OPTIONオプションが利用可能になりました。 その意味は、ビューの
INSERTおよび
UPDATEを使用して、追加または変更されるデータがビューの
WHERE句に限定されているかどうかを確認するチェックが追加されることです。 たとえば、古い本が選択されているビューがあり、このビューでは新しい本の追加を禁止する必要があります。
さらに、
security_barrierオプションでアドバタイズされたビューは、自動更新が停止しなくなりました。
security_barrierをより詳細に検討してください。
本にプロモーションコードを入力するフィールドを追加します。
本(一部の秘密の本を除く)とそのプロモーションコードを返すプレゼンテーション、およびRAISE NOTICEを通じて本の名前とコードを表示する関数を作成しましょう。
CREATE OR REPLACE VIEW vw_book_list AS SELECT b.* FROM book b WHERE b.name != ' №1'; CREATE OR REPLACE FUNCTION fn_book_promotion_code ( p_name text, p_code text ) RETURNS boolean AS $BODY$ BEGIN RAISE NOTICE 'Book "%" has code "%"', p_name, p_code; RETURN true; END $BODY$ LANGUAGE plpgsql COST 100;
(
fn_book_promotion_codeを呼び出して本のプロモーションコードを表示することにより)このビューから選択を行い、クエリプランを見てみましょう。
SELECT name, promotion_code FROM vw_book_list l WHERE fn_book_promotion_code ( l.name, l.promotion_code );
行は順番に読み取られ、フィルターでは、ブックの名前の対応が最初にチェックされ、次に
fn_book_promotion_code関数が
呼び出されることに注意してください。 関数を呼び出すコストを削減し、クエリ結果とクエリプランの変更点を確認してみましょう。
CREATE OR REPLACE FUNCTION fn_book_promotion_code ( p_name text, p_code text ) RETURNS boolean AS $BODY$ BEGIN RAISE NOTICE 'Book "%" has code "%"', p_name, p_code; RETURN true; END $BODY$ LANGUAGE plpgsql COST 0.01; SELECT name, promotion_code FROM vw_book_list l WHERE fn_book_promotion_code ( l.name, l.promotion_code );
コストは悲惨な関数を呼び出すコストであるため、スケジューラーはまずそれを呼び出し、次に本の名前をチェックします。 これにより、秘密の本のコードを見つけることができます。 このような状況を防ぐには、vw_book_listビューを
security_barrierオプションで作成する必要があります。
CREATE OR REPLACE VIEW vw_book_list WITH ( security_barrier = true ) AS SELECT b.* FROM book b WHERE b.name != ' №1'; SELECT name, promotion_code FROM vw_book_list l WHERE fn_book_promotion_code ( l.name, l.promotion_code );
これで、スケジューラーは、個別のサブクエリとして関数呼び出しを使用してフィルターを割り当てました。
vw_book_listビューは自動更新のままです。
UPDATE vw_book_list SET promotion_code = 'CODE_555' WHERE name = ' №2';
マテリアライズドビューの変更
PostgreSQL 9.3で導入されたマテリアライズドビューの主な問題は、排他(
ACCESS EXCLUSIVE )ロックを使用して、ビューの更新時にビューを使用できないようにすることでした。 9.4では、マテリアライズドビューの更新に
EXCLUSIVEロックを使用する
REFRESH MATERIALIZED VIEW コマンドにCONCURRENTLYオプションが追加されました。これは、
SELECTクエリ中に発生する競合する
ACCESS SHAREロックと互換性があります。 舞台裏では、このような更新により、このビューの一時バージョンが作成され、比較が行われ、相違点がある場合、対応する
INSERTおよび
DELETEコマンドが実行されます。 このアプローチでは、マテリアライズドビューの1つ以上のフィールドで
UNIQUE INDEXを作成する必要があります。 実際に見てみましょう:
構成パラメーターを設定するALTER SYSTEMコマンド
このコマンドを使用すると、SQLクエリを介してサーバー構成パラメーターを変更できます。 セッション(またはトランザクション)に適用される
SETおよび
set_configコマンドとは異なり、変更は永続的です。 実際、パラメーターは$ PGDATA / postgresql.auto.confファイルに追加されます。このファイルは、postgresql.confの読み取り後に(起動時または
SIGHUPシグナルの受信時に)サーバーによって読み取られます。 このコマンドの例:
行戻り関数のWITH ORDINALITYオプション
ネスト解除関数(および文字列のセットを返す他の関数)には、
WITH ORDINALITYオプションが追加され、文字列の順序が表示されます。 また、unnestでは、それぞれが個別の列になる複数の配列をリストできます。
SELECT * FROM unnest ( ARRAY['cat', 'dog', 'mouse'], ARRAY['Tom', 'Jack', 'Lili'] ) WITH ORDINALITY AS t ( cat, dog, mouse );
集計データの新機能
標準の集計関数(
sum 、
avg 、
corrなど)に、順序付きセットおよび仮説シリーズのセットの関数が追加されました。
集約関数に分類されるデータをフィルタリングするためのオプションも登場しました:
GINおよびGiSTインデックスの改善
全文検索に使用される
GINインデックス(複数のフィールド)がより高速になり、スペースを節約します。
GiSTは
inetおよび
cidrタイプのサポートを導入しました:
EXPLAINコマンド出力の改善
EXPLAINコマンドの出力にグループ化がある場合、データがグループ化される列が表示されます。 さらに、クエリプランの
計画時間が表示されるようになりました。
EXPLAIN ANALYZE SELECT s.value, count ( * ) FROM salary s GROUP BY s.value HAVING count ( * ) >= 2;
ビットマップヒープスキャンが使用される場合、一致するブロックの数(
正確 )と欠落しているブロックの数(
非可逆 ):
キャッシュを暖める
新しい
pg_prewarm拡張機能では、同じ名前の関数を使用できます。これにより、必要なエンティティがキャッシュにロードされます(システムOSまたはPostgreSQL)。 これがどのように起こるか見てみましょう。
最初に、拡張機能をインストールし、テストテーブルを作成します。
CREATE EXTENSION pg_prewarm; CREATE TABLE big AS SELECT array_to_string ( array_agg ( tx ), '' ) || '#' || generate_series ( 1, 10000 ) AS value FROM ( SELECT 'a' || generate_series ( 1, 1000 ) AS x ) t;
次に、PostgreSQLサーバーを停止し、OSキャッシュをディスクにフラッシュして、サーバーを再起動します(OSには異なるコマンドがある場合があります)。
/etc/init.d/postgresql-9.4 stop sync /etc/init.d/postgresql-9.4 start
クエリをテストテーブルに向けて、データの送信元を観察します。
キャッシュにはまだ何もないため、データはディスクから読み取られます(
共有読み取り )が、後続のリクエストごとにキャッシュがいっぱいになる(
共有ヒット )ことがわかります。
PostgreSQLサーバーを再度停止し、OSキャッシュをリセットして、サーバーを起動します。 繰り返しになりますが、
EXPLAINの結果を見てみましょうが、その前に、テストテーブルのデータでキャッシュを埋めます。
すべてのデータはすでにキャッシュにあります。
外部テーブルのトリガー
PostgreSQL 9.3は
postgres_fdw拡張を導入しました。これにより、別のデータベース(いわゆる
外部テーブル)にあるテーブルへの読み取り/書き込みアクセスを取得できます。 9.4では、それらのトリガーを作成できるようになりました。
外部テーブルを作成します。
N / Aという名前の都市の追加を禁止するトリガーを作成して確認します。
しかし、test0データベースでは、このトリガーは「表示されない」ため、任意の都市名を指定できます。
jsonおよび新しいjsonbデータ型の変更
間違いなく、新しい
jsonbタイプは、PostgreSQL 9.4で最も期待されていた革新でした。 構文的には、
jsonと違いはありませんが、データは拡張バイナリ形式で保存されるため、新しいデータの追加は遅くなりますが、処理速度は高くなります。 一般的に、
jsonbに JSONを保存する方が適切
です 。
jsonbには、インデックス(
GIN 、
btree 、および
hash )を作成する機能があります。
GINには2つの演算子クラスがあります:
- 標準(jsonb_ops)-@>、?、?&and?|をサポート
- jsonb_path_ops-@>演算子をサポート
jsonb_path_ops演算子クラスは1つの演算子のみをサポートしますが、
jsonb_opsよりも効率的であり、同じデータに対して通常より少ないスペースを
占有します。
JSONを操作するための新しい関数には、次のものがあります(それぞれ
jsonbタイプの場合、jsonb_ *):
- json_array_elements_text-JSON配列をtext型の値のセットに展開します
- json_array_elements_text-値をJSON配列に折り畳む
- json_object-テキスト配列からJSONオブジェクトを構築する
- json_typeof-JSON値タイプ情報
JSONタイプとPostgreSQLタイプには次の関係があります(セマンティクスが異なるPostgreSQLではNULLであるため、
nullに相当するものはありません):
JSON型 | PostgreSQLタイプ |
---|
ひも | テキスト |
数 | 数値 |
ブール値 | ブール値 |
JSONを操作してみましょう。
演算子@>、? 他のいくつかは
jsonbタイプに固有です。
jsonbとパフォーマンステストの詳細については、別の記事を参照してください。
サーバーの改善(特に、SSL、VACUUM、backgound_workersに関連するもの)は、この記事では考慮されていません。 詳細については、変更ログを参照してください。 結論として、PostgreSQLはリレーショナルとNoSQLの両方向に自信を持って動いていることに注意したいと思います。 徐々に新しい機能が追加され、将来のバージョンで改善されますが、これは朗報です。
便利なリンク:
ご清聴ありがとうございました。