当前位置: 代码网 > it编程>数据库>MsSqlserver > PostgreSQL中GIN索引的三种使用场景

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

2025年07月21日 MsSqlserver 我要评论
数组类型当在 postgresql 中使用 gin 索引来处理数组类型时,可以通过以下示例来说明:假设有一个表books,其中有一个列tags存储了书籍的标签信息,使用数组类型来表示。现在我们想要创建

数组类型

当在 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索引内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网! 

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com