sql >> データベース >  >> RDS >> PostgreSQL

ネストされていないjsonb列でのGROUPBY+COUNTDISTINCTの最適化

    idを想定 UNIQUEだけでなく -UNIQUE INDEXによって強制されます -しかし、NOT NULL 。 (これはテーブル定義にありません。)

    SELECT meta_split.key, meta_split.value, count(*)
    FROM   voc_cc348779bdc84f8aab483f662a798a6a v
    CROSS  JOIN LATERAL jsonb_each(v.meta) AS meta_split
    GROUP  BY meta_split.key, meta_split.value;
    

    短い同等物:

    SELECT meta_split.key, meta_split.value, count(*)
    FROM   voc_cc348779bdc84f8aab483f662a798a6a v, jsonb_each(v.meta) AS meta_split
    GROUP  BY 1, 2;
    

    LEFT [OUTER] JOIN 次のテストWHERE meta_split.value IS NOT NULLが原因で、ノイズが発生しました INNER JOINを強制します とりあえず。 CROSS JOINの使用 代わりに。

    また、jsonb とにかく同じレベルで重複キーを許可しません(同じidを意味します) ポップアップできるのは1回のみです (key, value)ごと )、DISTINCT ただ高価なノイズです。 count(v.id) 同じことをより安くします。そしてcount(*) 同等で安価ですが、idを想定しています NOT NULLです 上部に記載されているように。

    count(*) 別の実装があります count(<value>)よりもわずかに高速です 。 count(v.*)とは微妙に異なります 。何があっても、すべての行をカウントします。他の形式はNULLをカウントしませんが 値。

    つまり、idである限り NULLにすることはできません -上部に記載されているように。 id 本当にPRIMARY KEYである必要があります 、とにかく内部的に一意のBツリーインデックスとすべての列で実装されます-id ここに-NOT NULLです 暗黙のうちに。または、少なくともNOT NULLUNIQUE INDEX 代替として完全に適格ではありませんが、それでもNULLを許可します 等しいとは見なされず、複数回許可される値。参照:

    それとは別に、すべての行をとにかく読み取る必要があるため、ここではインデックスは役に立ちません。したがって、これが非常に安くなることは決してありません。ただし、62k行 jsonbに膨大な数のキーがない限り、これは決して不自由な行数ではありません。 列。

    それをスピードアップするための残りのオプション:

    1. デザインを正規化します。 JSONドキュメントのネスト解除は無料ではありません。

    2. マテリアライズドビューを維持します。実現可能性とコストは、書き込みパターンに大きく依存します。

    ここで、インデックスが再び役割を果たす可能性があります...




    1. MySQLコマンドプロンプトを介してWordPress管理者パスワードをリセットする方法

    2. djangoプロダクションでのデータベースの移行

    3. MYSQLのテーブルにランダムな数値を挿入する

    4. 11i/R12のゲストユーザーパスワード