Skip to content

PostgreSQL GIN Index: Complete Guide

Understand what a GIN index is and how it works

PostgreSQL supports several types of indexes, including B-Tree, Hash, GiST, SP-GiST, BRIN, and GIN. Each of them offers different characteristics and is better suited to one scenario than another. One of the most useful and popular types is the PostgreSQL GIN index.

In this guide, you will see what a GIN index is, why it is so important, its syntax, and when to use it. Let’s dive in!

What Is a PostgreSQL GIN Index?

GIN stands for “Generalized Inverted Index” and is designed for handling composite values. In detail, inverted indexes store a separate entry for each component value. Thus, this index speeds up queries that search for specific element values within the indexed composite items. For example, queries that search for text documents containing specific words.

GIN indexes have been part of PostgreSQL since version 11. Specifically, the current implementation is maintained by Teodor Sigaev and Oleg Bartunov. Check out their site to learn more about how GIN indexes work.

PostgreSQL GIN Index Syntax

The syntax for creating a GIN index in PostgreSQL is:

CREATE INDEX <index_name> 
ON <table_name> 
USING GIN (<column_name>);

Replace <index_name> with the desired name for your GIN index. It should be unique within the schema. Also, replace <table_namee> with the name of the table you want to apply the GIN index on. Then, specify the column on which the index will be applied in <column_name>.

Keep in mind that GIN indexes can be created on both single and multiple columns. In case of more than one column, write them as a comma-separated list:

CREATE INDEX <index_name> 
ON <table_name> 
USING GIN (<column_name1>, <column_name2>, ..., <column_nameN>);

Use Cases

Let’s explore the use cases where PostgreSQL GIN indexes are effective, understanding what benefits they introduce.

1. Generic Text Search and Full-Text Search

Text search is a fundamental functionality for numerous applications, and many features rely on that. To provide a great user experience, you must achieve efficient full-text search. This is where a GIN index can help you.

When dealing with large volumes of text data, a PostgreSQL GIN index on text columns can significantly enhance search performance. Instead of scanning the entire dataset for matching text, the index allows the DBMS to quickly identify relevant documents or records. This optimization translates into faster search results, enabling users to find information quickly and efficiently.

This is why the PostgreSQL documentation recommends using GIN indexes to optimize full-text queries.

Example

Suppose you have a table called documents with a text column named content, and you want to find all documents containing the word “PostgreSQL” efficiently.

Create a GIN index on the content column:

CREATE INDEX gin_content_idx ON documents USING GIN(to_tsvector('english', content));

Then, perform a full-text search for the desired word using the @@ operator:

SELECT * FROM documents WHERE to_tsvector('english', content) @@ to_tsquery('english', 'PostgreSQL');

2. Searching for Elements in Arrays

PostgreSQL supports arrays as a native data type, allowing you to store a collection of values in a single column. Adding GIN indexes on array columns helps to achieve efficient queries and filters on array elements. In scenarios where you need to find records that match specific values within the arrays, GIN indexes greatly speed up these operations.

Example

Assume you have a products table containing an array column named tags. Your goal is to find all products tagged with “Electronics” efficiently.

Add the GIN index:

CREATE INDEX gin_tags_idx ON products USING GIN(tags);

Then perform the query:

SELECT * FROM products WHERE 'Electronics' = ANY(tags);

3. Retrieving JSONB Documents

The jsonb data type is a flexible way to handle semi-structured in PostgreSQL. GIN indexes can be applied to JSON data, allowing for accelerated searches for specific JSON keys or values within JSON documents.

“GIN indexes can be used to efficiently search for keys or key/value pairs occurring within a large number of jsonb documents” – JSON ypes

This feature is particularly valuable in applications that rely on a lot of structured data in JSON format. Similarly, adding a PostgreSQL GIN index is a good way to optimize queries on hstore columns.

Example

Consider that you have a table called documents with a data JSONB column. You want to retrieve all documents where the key "author" exists and has the value "John Smith".

Define the GIN index:

CREATE INDEX gin_data_idx ON documents USING GIN(data);

Next, perform a query to retrieve the desired documents using the @> JSONB “contain” operator:

SELECT * FROM documents WHERE data @> '{"author": "John Smith"}';

Conclusion

In this article, you learned what a GIN index in PostgreSQL is, how to define one, and its most important use cases. As learned here, GIN indexes are inverted indexes that work great with composite data. For example, it enables you to optimize full-text queries and queries on JSON or array data.

Thanks for reading! I hope you found this article helpful.

nv-author-image

Antonello Zanini

I'm a software engineer, but I prefer to call myself a Technology Bishop. Spreading knowledge through writing is my mission.View Author posts

Want technical content like this in your blog?