私はかなりPostgresを新しく使い、現在9.6を使用しています。 jsonbドキュメントを使用してpostgresで全文検索を実装しようとすると、ネストされた配列の検索結果が遅くなっていました。私は 'explain'コマンドを使用しましたが、インデックスを使用しませんでした。 は、単純化の目的のために私は調査するテーブルを作成しました:PostgreSQLでネストされたJSONB配列要素を検索するためのインデックス
CREATE TABLE book (
id BIGSERIAL NOT NULL,
data JSONB NOT NULL
);
マイ可能なインデックス:
CREATE INDEX book_author_idx
ON book USING GIN (to_tsvector('english', book.data ->> 'author'));
CREATE INDEX book_author_name_idx
ON book USING GIN (to_tsvector('english', book.data -> 'author' ->> 'name'));
、文書を埋めるためにいくつかのデータ:
INSERT INTO book (data)
VALUES (CAST('{"author": [{"id": 0, "name": "Cats"}, ' ||
' {"id": 1, "name": "Dogs"}]}' AS JSONB));
を私は検索することができますよ次のクエリを使用するブック要素の場合は、インデックスを使用しません。私の実際の120k製品のデータでは約1200msかかりますが、インデックスでの他の検索は0.2msです。これとは対照的に
EXPLAIN ANALYZE
SELECT
id,
data ->> 'author' AS author
FROM book, jsonb_array_elements(data #> '{author}') author_array
WHERE to_tsvector('english', author_array ->> 'name') @@ to_tsquery('cat');
次のクエリはbook_author_name_idxを使用していますが、理由は配列構造のものを見つけることができません。
EXPLAIN ANALYZE
SELECT
id,
data ->> 'author' AS author
FROM book
WHERE to_tsvector('english', data -> 'author' ->> 'name') @@ to_tsquery('cat');
言語インデックスを使用するためにクエリを調整するにはどうすればよいですか? 私は著者のために新しいテーブルを作成し、IDのみを参照できることを知っていますが、パフォーマンスのためにすべてのデータを1つのテーブルに保存したいと思います。
'' LATERAL JOIN'に 'unnest()'とそのフレンズ( 'jsonb_array_elements()'のような結果セット生成関数を使用すると、(少なくともそれらから計算されたプロパティの)インデックスは使用できなくなります。この構造体に固執するなら、あなたの 'jsonb'カラムから' tsvector'値を生成するためのカスタムの 'IMMUTABLE'関数を作成し、あなたのインデックスとクエリの両方でその関数を使用する必要があります。 – pozs
興味深いのは、 'tsvector'には組み込みの集約がないということです。そのため、名前を文字列として集約する必要があります。(基本的なルールで)2)' tsvector'のカスタム集約を構築する3 )は巧妙な再帰的なCTEを使用します(連結がすでに存在しているため)。 – pozs