web-dev-qa-db-ja.com

Postgresのjsonbのベストインデックス

約50万行を含むテーブルがあります。データベーステーブルは、数百万のレコードになると予想されます。

これはテーブルがどのように見えるかです:

CREATE TABLE public.influencers
(
    id integer NOT NULL DEFAULT nextval('influencers_id_seq'::regclass),
    location jsonb,
    gender text COLLATE pg_catalog."default",
    birthdate timestamp without time zone,
    ig jsonb,
    contact_info jsonb,
    created_at timestamp without time zone DEFAULT now(),
    updated_at timestamp without time zone DEFAULT now(),
    categories text[] COLLATE pg_catalog."default",
    search_field text COLLATE pg_catalog."default",
    search_vector tsvector,
    ig_updated_at timestamp without time zone,
    CONSTRAINT influencers_pkey PRIMARY KEY (id),
    CONSTRAINT ig_id_must_exist CHECK (ig ? 'id'::text),
    CONSTRAINT ig_username_must_exist CHECK (ig ? 'username'::text)
)

そして、これらは私たちが効率的に実行する必要があるクエリの一部です:

SELECT  "public"."influencers".*
FROM "public"."influencers"
WHERE (ig->'follower_count' IS NOT NULL)
ORDER BY (ig->'follower_count') DESC
LIMIT 9
OFFSET 0

SELECT *
FROM "public"."influencers"
WHERE (ig->'follower_count' >= '5000')
LIMIT 9 

SELECT SUM(CAST(ig ->> 'follower_count' AS integer))
FROM "public"."influencers"
WHERE (ig->'follower_count' >= '5000')
  AND (ig->'follower_count' <= '10000')
  AND (ig->'follower_count' IS NOT NULL)

ig -> follower_countは数値です。

GINインデックスは主に複合アイテム(テキスト)を検索するためのものであることを読んだので、使用するのに最適なインデックスはBTREEだと思います。それは正しいでしょうか?

3
borjagvo

GINインデックスは jsonb演算子[〜#〜]以外では機能しません[〜#〜]? ?& ?| @>。明らかに、比較演算子の使用>=および<=はそのリストにありません。そして、それが役立つ可能性のあるすべての演算子もリストに含まれていません(つまり、インデックスは何もしません)。

つまり、インデックス付きの比較演算子が必要です。btreeが必要になります。

CREATE INDEX ON public.influencers ((ig->'follower_count'));

とはいえ、これはばかげていると思います。 follower_count実際のテーブルの適切な列として、パフォーマンス上のメリットを享受してください。

3
Evan Carroll