Let me show you different ways to create and use GIN indexes with JSONB:
-- 1. Basic GIN index for all keys in JSONB
CREATE INDEX idx_data_gin ON your_table USING GIN (data);
-- 2. GIN index for specific operator
CREATE INDEX idx_data_gin_path_ops ON your_table USING GIN (data jsonb_path_ops);
-- 3. GIN index for specific key
CREATE INDEX idx_specific_key ON your_table USING GIN ((data -> 'specific_key'));
-- 4. GIN index for array elements
CREATE INDEX idx_array_elements ON your_table USING GIN ((data -> 'array_field'));
-- 5. Partial GIN index
CREATE INDEX idx_partial_gin ON your_table USING GIN (data)
WHERE data ? 'important_key';
Example queries that use these indexes:
-- Contains operator ?
SELECT * FROM your_table WHERE data ? 'key_name';
-- Path matching @>
SELECT * FROM your_table
WHERE data @> '{"status": "active", "type": "user"}';
-- Key-value match
SELECT * FROM your_table
WHERE data->>'status' = 'active';
-- Array operations
SELECT * FROM your_table
WHERE data->'tags' ? 'urgent';
-- Complex nested queries
SELECT * FROM your_table
WHERE data @> '{"address": {"city": "New York"}}';
Monitoring index usage:
-- Check if index is being used
EXPLAIN ANALYZE
SELECT * FROM your_table
WHERE data @> '{"status": "active"}';
-- Index size
SELECT pg_size_pretty(pg_relation_size('idx_data_gin'));
-- Index statistics
SELECT * FROM pg_stat_user_indexes
WHERE indexrelname = 'idx_data_gin';
Best practices:
jsonb_path_ops
when you only need containment (@>
) queriesWould you like me to explain any specific type of GIN indexing in more detail?