Postgres 中 jsonb 的最佳索引

bor*_*gvo 3 postgresql index btree gist-index json

我们有一个包含大约 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)
)
Run Code Online (Sandbox Code Playgroud)

这些是我们需要高效执行的一些查询:

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)
Run Code Online (Sandbox Code Playgroud)

ig -> follower_count 是数值。

我读到 GIN 索引主要用于搜索复合项(文本),所以我猜最好使用的索引是 BTREE。那会是正确的吗?

Eva*_*oll 5

GIN 索引不适用于任何jsonb 运算符 EXCEPT ? ?& ?| @>。显然,您使用比较运算符>=<=没有出现在该列表中。并且它可以帮助的所有那些运算符也不在列表中(意味着索引不会做任何事情)afaik。

这意味着需要索引比较运算符,您将需要一个 btree。

CREATE INDEX ON public.influencers ((ig->'follower_count'));
Run Code Online (Sandbox Code Playgroud)

综上所述,我认为这是愚蠢的。只需将其follower_count作为适当的列放在实际表上即可享受性能优势。