为什么在我的情况下不使用此GIN索引(jsonb)

时间:2019-08-21 08:03:13

标签: postgresql

我的代码在https://rextester.com/CBYD42261上,我使用'@>'与gin索引进行搜索,但使用Seq Scan进行了PostgreSQL。

DROP TABLE IF EXISTS sponsor_projects;

CREATE TABLE sponsor_projects (
    project_id BIGSERIAL PRIMARY KEY,
    sponsor_id bigint NOT NULL,
    status smallint NOT NULL DEFAULT 0,
    name character varying(64) NOT NULL,
    category character varying(10) NOT NULL,
    purpose jsonb NOT NULL,
    qrcode character varying(200) NOT NULL,
    plaform character varying(10) NOT NULL,
    budget double precision NOT NULL,
    budget_used double precision NOT NULL,
    sticker character varying(10) NOT NULL,
    spread character varying(10) NOT NULL,
    areas jsonb NOT NULL,
    paused boolean DEFAULT false,
    terminated boolean DEFAULT false,
    start_time timestamp(0) without time zone NOT NULL,
    end_time timestamp(0) without time zone,
    shops jsonb NOT NULL,
    created_by integer,
    created_at timestamp(0) without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at timestamp(0) without time zone NOT NULL DEFAULT CURRENT_TIMESTAMP,
    deleted boolean DEFAULT false,
    deleted_at timestamp(0) without time zone DEFAULT NULL::timestamp without time zone
);

-- Indices -------------------------------------------------------

CREATE INDEX idx_sponsor_projects_sponsor_id ON sponsor_projects(sponsor_id int8_ops);
CREATE INDEX idx_sponsor_projects ON sponsor_projects USING GIN (shops);


-- Insert Data ---------------------------------------------------
INSERT INTO "sponsor_projects"("sponsor_id","status","name","category","purpose","qrcode","plaform","budget","budget_used","sticker","spread","areas","paused","terminated","start_time","end_time","shops","created_by","created_at","updated_at","deleted","deleted_at")
VALUES
(1,0,E'京东广告',E'3C数码产品',E'["品牌宣传", "流量拉新"]',E'https://jd.com',E'不限',1000,0,E'标准桌贴',E'CPC',E'[{"id": "fc5d1d71-14b1-473d-9db2-c804b0d9ab6c", "path": [[116.68767, 39.877689], [116.712303, 39.868862], [116.704149, 39.8601], [116.6887, 39.865041]]}]',FALSE,FALSE,E'2019-08-20 06:51:26',NULL,E'[{"shop_id": 5}]',NULL,E'2019-08-21 14:55:01',E'2019-08-21 14:55:01',FALSE,NULL);

EXPLAIN ANALYZE
SELECT * FROM sponsor_projects t WHERE t.shops @> '[{"shop_id": 5}]';

它显示:

Seq Scan on sponsor_projects t  (cost=0.00..11.00 rows=1 width=893) (actual time=0.013..0.016 rows=1 loops=1)
  Filter: (shops @> '[{"shop_id": 1}]'::jsonb)
  Rows Removed by Filter: 8
Planning Time: 0.076 ms
Execution Time: 0.033 ms

使用Seq扫描,而不是杜松子酒索引。

我的代码怎么了?

请有人可以帮助我吗?

1 个答案:

答案 0 :(得分:2)

这是因为表仅包含一行,并且使用类似的小表进行顺序扫描总是更快。

要测试是否可以使用索引 ,请阻止在数据库会话中使用顺序扫描:

SET enable_seqscan = off;

然后PostgreSQL将尽可能使用索引。

请确保随后重设设置:

RESET enable_seqscan;