web-dev-qa-db-ja.com

PostgresでJSONデータを検索する場合、GINまたは複数のインデックス付き列のどちらがより効率的ですか?

たとえば、中程度の数の行(〜100,000程度)があり、いずれかの行に次のサンプルデータがあるjsonb列を持つテーブルがあるとします。

{"name":"Bob", "favoriteColor":"red", "someOtherObject": {"somethingElse": true}}

次の方が効率的ですか?

  1. Jsonb列でGINインデックスを使用し、次にPostgresの組み込みJSONクエリ関数を使用してデータを引き出します

  2. 検索できるものを表すためにいくつかの列を作成します。つまり、nameの1つの列、favoriteColorの1つの列などです。それらの列にBツリーインデックスを作成してから、select document from table where name = 'Bob'

  3. 他の解決策はありますか?

    ソリューションはlikeクエリを効率的にサポートして、特定の入力文字列で始まる値を検索できるようにする必要があることに注意してください。

5
Ben

JSONの利点は汎用性です。テーブル定義を変更せずに任意のキーを追加できます。アプリケーションがJSONを直接読み書きできる場合、便利かもしれません。

個別の列は、すべてのパフォーマンス面でjsonまたはjsonbを組み合わせたものよりも優れていますと他のいくつかの側面でも:より洗練された型システム、全機能(チェック、一意、外部キー制約、デフォルト値など)、テーブルが小さく、インデックスが小さく、クエリが高速です。

text列でのプレフィックスの一致には、text_pattern_opsインデックス:

または、より一般的には、anyLIKEパターンをサポートするトライグラムインデックス:

JSON(特にjsonb)を使い続ける一方で、さまざまなインデックス作成戦略もあります。 GINまたはBtreeだけが決定するものではありません。部分インデックス、式インデックス、さまざまな演算子クラス(特に:jsonb_path_ops)関連:

7

いくつかのこと

  • BtreeはスカラーよりもGINより高速です。
  • 複雑なアイテムでは、GINはスカラーよりもさらに遅くなります。

スカラー上にbtreeを作成していて、ルックアップがそれよりも複雑でない場合は、btreeが勝つことは明らかです。

0
Evan Carroll