PostgreSQL中GIN索引的三种使用场景

 更新时间:2025年07月21日 09:39:43   作者:岳麓丹枫001  
本文主要介绍了PostgreSQL中GIN索引的三种使用场景,包括数组类型、JSONB类型和全文搜索,具有一定的参考价值,感兴趣的可以了解一下

数组类型

当在 PostgreSQL 中使用 GIN 索引来处理数组类型时,可以通过以下示例来说明:

假设有一个表 books,其中有一个列 tags 存储了书籍的标签信息,使用数组类型来表示。现在我们想要创建一个 GIN 索引来加快对标签进行搜索的查询。

首先,创建 books 表:

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title VARCHAR(100),
    tags TEXT[]
);

接下来,插入一些示例数据:

INSERT INTO books (title, tags) VALUES
    ('Book 1', ARRAY['fiction', 'adventure']),
    ('Book 2', ARRAY['science', 'fiction']),
    ('Book 3', ARRAY['romance', 'fantasy']),
    ('Book 4', ARRAY['adventure']);

然后,创建 GIN 索引:

CREATE INDEX idx_books_tags_gin ON books USING GIN (tags);

现在,我们可以执行搜索查询,以便在 tags 列中查找包含特定标签的书籍。例如,查找包含标签 'fiction' 的书籍:

SELECT * FROM books WHERE tags @> ARRAY['fiction'];

lxm=# set enable_seqscan = off;
SET
lxm=# explain (verbose, analyse, costs, buffers)  SELECT * FROM books WHERE tags @> ARRAY['fiction'];
                                                        QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on public.books  (cost=8.00..12.01 rows=1 width=254) (actual time=0.023..0.025 rows=2 loops=1)
   Output: id, title, tags
   Recheck Cond: (books.tags @> '{fiction}'::text[])
   Heap Blocks: exact=1
   Buffers: shared hit=3
   ->  Bitmap Index Scan on idx_books_tags_gin  (cost=0.00..8.00 rows=1 width=0) (actual time=0.017..0.018 rows=2 loops=1)
         Index Cond: (books.tags @> '{fiction}'::text[])
         Buffers: shared hit=2
 Planning:
   Buffers: shared hit=1
 Planning Time: 0.126 ms
 Execution Time: 0.073 ms
(12 rows)


lxm=#
lxm=# SELECT * FROM books WHERE tags @> ARRAY['fiction'];
 id | title  |        tags
----+--------+---------------------
  1 | Book 1 | {fiction,adventure}
  2 | Book 2 | {science,fiction}
(2 rows)

这将返回匹配的书籍记录。

下面 SQL ,将返回同时包含 'fiction' 和 'adventure' 标签的书籍记录。

SELECT * FROM books WHERE tags @> ARRAY['fiction', 'adventure'];

lxm=# SELECT * FROM books WHERE tags @> ARRAY['fiction', 'adventure'];
 id | title  |        tags
----+--------+---------------------
  1 | Book 1 | {fiction,adventure}
(1 row)

lxm=# explain (verbose, analyse, costs, buffers) SELECT * FROM books WHERE tags @> ARRAY['fiction', 'adventure'];
                                                         QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on public.books  (cost=12.00..16.01 rows=1 width=254) (actual time=0.016..0.017 rows=1 loops=1)
   Output: id, title, tags
   Recheck Cond: (books.tags @> '{fiction,adventure}'::text[])
   Heap Blocks: exact=1
   Buffers: shared hit=4
   ->  Bitmap Index Scan on idx_books_tags_gin  (cost=0.00..12.00 rows=1 width=0) (actual time=0.012..0.012 rows=1 loops=1)
         Index Cond: (books.tags @> '{fiction,adventure}'::text[])
         Buffers: shared hit=3
 Planning:
   Buffers: shared hit=1
 Planning Time: 0.087 ms
 Execution Time: 0.034 ms
(12 rows)

jsonb 类型

当使用 PostgreSQL 的 JSONB 数据类型存储和查询 JSON 数据时,可以使用 GIN(Generalized Inverted Index)索引来提高查询性能。GIN 索引适用于包含大量不同的键值对的 JSONB 列。

下面是一个 PostgreSQL 中使用 GIN 索引的 JSONB 示例:

首先,创建一个包含 JSONB 列的表:

drop table if exists my_table ;
CREATE TABLE my_table (
    id SERIAL PRIMARY KEY,
    data JSONB
);

INSERT INTO my_table (data)
VALUES ('{"name": "John", "age": 30, "address": {"city": "New York", "state": "NY"}}'),
       ('{"name": "Alice", "age": 25, "address": {"city": "San Francisco", "state": "CA"}}'),
       ('{"name": "Bob", "age": 35, "address": {"city": "Seattle", "state": "WA"}}');

接下来,创建一个 GIN 索引来加速 JSONB 列的查询:

CREATE INDEX my_table_data_gin_index ON my_table USING GIN (data);

现在,可以使用 GIN 索引来执行 JSONB 列的查询。例如,查找居住在纽约的人:

set enable_seqscan to off;
SELECT * FROM my_table WHERE data @> '{"address": {"city": "New York"}}';
explain (verbose, analyse, costs, buffers) SELECT * FROM my_table WHERE data @> '{"address": {"city": "New York"}}';


lxm=# set enable_seqscan to off;
SET
lxm=#
lxm=# SELECT * FROM my_table WHERE data @> '{"address": {"city": "New York"}}';
 id |                                    data
----+-----------------------------------------------------------------------------
  1 | {"age": 30, "name": "John", "address": {"city": "New York", "state": "NY"}}
(1 row)

lxm=# explain (verbose, analyse, costs, buffers)
lxm-#  SELECT * FROM my_table WHERE data @> '{"address": {"city": "New York"}}';
                                                           QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on public.my_table  (cost=16.00..20.01 rows=1 width=36) (actual time=0.022..0.022 rows=1 loops=1)
   Output: id, data
   Recheck Cond: (my_table.data @> '{"address": {"city": "New York"}}'::jsonb)
   Heap Blocks: exact=1
   Buffers: shared hit=5
   ->  Bitmap Index Scan on my_table_data_gin_index  (cost=0.00..16.00 rows=1 width=0) (actual time=0.014..0.014 rows=1 loops=1)
         Index Cond: (my_table.data @> '{"address": {"city": "New York"}}'::jsonb)
         Buffers: shared hit=4
 Planning:
   Buffers: shared hit=1
 Planning Time: 0.068 ms
 Execution Time: 0.040 ms
(12 rows)

这将返回居住在纽约的人的记录。

GIN 索引还可以在 JSONB 列的键上进行查询。例如,查找年龄大于等于 30 岁的人:

SELECT * FROM my_table WHERE data ->> 'age' >= '30';
explain (verbose, analyse, costs, buffers) SELECT * FROM my_table WHERE data ->> 'age' >= '30';

create index idx_my_table_data_age on my_table using gin((data->>'age'));

这将返回年龄大于等于 30 岁的人的记录。

使用 GIN 索引可以加快对 JSONB 列的查询,尤其是在包含大量不同键值对的情况下。请根据你的具体需求和数据模式进行调整和优化。

全文搜索

当在 PostgreSQL 中使用 GIN 索引进行全文搜索时,可以使用 tsvector 和 tsquery 数据类型以及相关的函数来实现。以下是一个示例:

假设我们有一个表 articles,其中有一个列 content 存储了文章的内容。我们想要创建一个 GIN 索引来支持全文搜索功能。

首先,创建 articles 表:

CREATE TABLE articles (
    id SERIAL PRIMARY KEY,
    title VARCHAR(100),
    content TEXT
);

接下来,插入一些示例数据:

INSERT INTO articles (title, content) VALUES
    ('Article 1', 'This is the content of article 1.'),
    ('Article 2', 'Here is the content for article 2.'),
    ('Article 3', 'This article discusses various topics.'),
    ('Article 4', 'The content of the fourth article is different.');

然后,为 content 列创建一个辅助列 tsvector,该列将存储已处理的文本索引:

ALTER TABLE articles ADD COLUMN content_vector tsvector;

接下来,更新 content_vector 列的值,将 content 列的文本转换为 tsvector 类型:

UPDATE articles SET content_vector = to_tsvector('english', content);

现在,我们可以创建 GIN 索引:

CREATE INDEX idx_articles_content_gin ON articles USING GIN (content_vector);

这将创建一个基于 content_vector 列的 GIN 索引,以支持全文搜索。

接下来,我们可以执行全文搜索查询,使用 tsquery 类型来指定搜索条件。例如,查找包含单词 'content' 的文章:

SELECT * FROM articles WHERE content_vector @@ to_tsquery('english', 'content');

到此这篇关于PostgreSQL中GIN索引使用场景的文章就介绍到这了,更多相关PostgreSQL GIN索引内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

相关文章

  • PostgreSQL中GIN索引的三种使用场景

    PostgreSQL中GIN索引的三种使用场景

    本文主要介绍了PostgreSQL中GIN索引的三种使用场景,包括数组类型、JSONB类型和全文搜索,具有一定的参考价值,感兴趣的可以了解一下
    2025-07-07
  • PostgreSQL核心原理之数据库偶尔会卡顿的原因分析

    PostgreSQL核心原理之数据库偶尔会卡顿的原因分析

    PostgreSQL功能强大、稳定可靠的开源关系型数据库系统,广泛应用于各种规模的企业和项目中,本文将从PostgreSQL的核心原理出发,深入剖析导致“偶尔卡顿”的常见原因,并结合底层机制进行解释,帮助 DBA 和开发者理解问题本质,从而更有效地排查与优化,感兴趣的朋友一起看看吧
    2026-02-02
  • 无公网IP环境下的PostgreSQL远程访问方案

    无公网IP环境下的PostgreSQL远程访问方案

    本文提出了一种基于内内网穿透技术的PostPostQL远程访问解决方案,该方案无需公网IP,配置简单且安全性可控,支持扩展性强,通过三步实现:隧道建立、端口映射和身份验证,实测延迟5-ms、带宽NMbps,适用于开发、数据查询和报表导出场景,需要的朋友可以参考下
    2026-04-04
  • postgresql高级应用之合并单元格的思路详解

    postgresql高级应用之合并单元格的思路详解

    这篇文章主要介绍了postgresql高级应用之合并单元格,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05
  • PostgreSQL 向量扩展插件pgvector安装和使用

    PostgreSQL 向量扩展插件pgvector安装和使用

    本文主要介绍了PostgreSQL 向量扩展插件pgvector安装和使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2026-05-05
  • postgresql 常用SQL语句小结

    postgresql 常用SQL语句小结

    postgresql使用过程中常用到的一些sql语句,方便我们快速使用查询一些操作特整理一下,方便需要的朋友
    2022-11-11
  • postgreSQL 数字与字符串类型转换操作

    postgreSQL 数字与字符串类型转换操作

    这篇文章主要介绍了postgreSQL 数字与字符串类型转换操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • PostgreSQL LIST、RANGE 表分区的实现方案

    PostgreSQL LIST、RANGE 表分区的实现方案

    这篇文章主要介绍了PostgreSQL LIST、RANGE 表分区的实现方案,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • Postgres数据库安装、配置、使用DBLink的实例详解

    Postgres数据库安装、配置、使用DBLink的实例详解

    文章介绍PostgreSQL的DBLink技术,用于跨数据库实例查询,解决数据分散问题,支持多种数据库类型,安装需检查插件并配置连接参数,便于实现多实例数据汇总,感兴趣的朋友跟随小编一起看看吧
    2025-07-07
  • PostgreSQL远程连接配置的实现

    PostgreSQL远程连接配置的实现

    本文主要介绍了在Windows上通过Navicat远程连接PostgreSQL的配置方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06

最新评论