Yandex Cloud
Search
Contact UsGet started
  • Blog
  • Pricing
  • Documentation
  • All Services
  • System Status
    • Featured
    • Infrastructure & Network
    • Data Platform
    • Containers
    • Developer tools
    • Serverless
    • Security
    • Monitoring & Resources
    • ML & AI
    • Business tools
  • All Solutions
    • By industry
    • By use case
    • Economics and Pricing
    • Security
    • Technical Support
    • Customer Stories
    • Start testing with double trial credits
    • Cloud credits to scale your IT product
    • Gateway to Russia
    • Cloud for Startups
    • Education and Science
    • Yandex Cloud Partner program
  • Blog
  • Pricing
  • Documentation
© 2025 Direct Cursus Technology L.L.C.
Yandex Managed Service for PostgreSQL
  • Getting started
    • Resource relationships
    • Planning a cluster topology
    • Networking in Managed Service for PostgreSQL
    • Quotas and limits
    • Storage in Managed Service for PostgreSQL
    • Backups
    • Assigning roles
    • Managing connections
    • Replication
    • Maintenance
    • Supported clients
    • PostgreSQL settings
    • Indexes
    • SQL command limits
  • Access management
  • Pricing policy
  • Terraform reference
  • Monitoring metrics
  • Audit Trails events
  • Public materials
  • Release notes

In this article:

  • Specialized indexes
  • Index bloating
  • Bloating scenarios
  • Native maintenance
  • pg_repack extension
  1. Concepts
  2. Indexes

Indexes in PostgreSQL

Written by
Yandex Cloud
Updated at April 25, 2025
  • Specialized indexes
  • Index bloating
    • Bloating scenarios
    • Native maintenance
    • pg_repack extension

A database index is an auxiliary structure that helps you find data in tables faster. It works in the same way as an alphabetic index for quick access to the information you need.

In relational databases such as PostgreSQL, data is stored in linked tables. Here is an example of database structure:

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    name VARCHAR(255),
    price DECIMAL(10,2),
    stock_quantity INTEGER,
    category_id INTEGER,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

--  Index for quick search by product name
CREATE INDEX idx_products_name ON products(name);

When running search queries without an index, the entire table has to be scanned, which requires O(n) operations, while a search with an index needs O(log n) operations.

Specialized indexesSpecialized indexes

PostgreSQL supports various index types to optimize specific operations:

CREATE TABLE pickup_points (
    id SERIAL PRIMARY KEY,
    address TEXT,
    coordinates POINT,
    working_hours JSONB,
    current_load INTEGER,
    updated_at TIMESTAMP
);

-- B-tree index
CREATE INDEX idx_pickup_basic ON pickup_points(id);

-- GiST index for geodata
CREATE INDEX idx_pickup_location ON pickup_points USING gist(coordinates);

-- BRIN index for temporary data
CREATE INDEX idx_pickup_load_history ON pickup_points USING brin(updated_at)
WHERE current_load IS NOT NULL;

Example of a complex query using various indexes:

SELECT p.*, 
       p.coordinates <-> POINT(37.5, 55.7) as distance,
       i.quantity as items_available
FROM pickup_points p
JOIN inventory i ON i.pickup_point_id = p.id
WHERE i.product_id = 12345
  AND p.current_load < 80
  AND p.coordinates <@ circle '((37.5, 55.7), 5000)'
ORDER BY distance
LIMIT 5;

For more information about index types, see PostgreSQL.

Index bloatingIndex bloating

Updating data in PostgreSQL requires updating all related indexes. With intensive data updates, indexes grow in size since outdated data versions remains in the index until maintenance operations are complete.

Example of an update operation:

-- Updating creates new versions in indexes
UPDATE products 
SET price = price * 0.8, 
    updated_at = CURRENT_TIMESTAMP 
WHERE category_id = 5;

Index bloating is a critical performance issue in PostgreSQL. When processing a high number of transactions, degraded database performance can severely disrupt the system, especially during peak load periods.

Bloating scenariosBloating scenarios

Here is an example of a data structure with multiple indexes:

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    customer_id INTEGER,
    pickup_point_id INTEGER,
    status VARCHAR(50),
    items JSONB,
    total_amount DECIMAL(10,2),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_orders_customer ON orders(customer_id);
CREATE INDEX idx_orders_status ON orders(status, created_at);
CREATE INDEX idx_orders_pickup ON orders(pickup_point_id, status);

Operations that cause index bloating:

-- Order status update
UPDATE orders 
SET status = 'ready_for_pickup',
    updated_at = CURRENT_TIMESTAMP
WHERE pickup_point_id = 123 
  AND status = 'processing';

-- Bulk status updates
UPDATE orders 
SET status = 'archived'
WHERE created_at < NOW() - INTERVAL '3 months' 
  AND status = 'completed';

Native maintenanceNative maintenance

The standard index maintenance method uses the REINDEX command:

REINDEX INDEX idx_orders_status;

This operation requires a table lock, which may be impossible under high loads.

pg_repack extensionpg_repack extension

The pg_repack extension reorganizes tables and indexes without long-term locks. To learn how to update and run pg_repack in a Managed Service for PostgreSQL cluster, see Using pg_repack.

Was the article helpful?

Previous
PostgreSQL settings
Next
SQL command limits
© 2025 Direct Cursus Technology L.L.C.