索引是数据库中预构建的数据结构,用于加速数据检索。其核心作用是将全表扫描(Full Table Scan)转换为对数级或常数级搜索,显著提升查询性能,但会增加插入、更新、删除操作的开销(需同步维护索引)。PostgreSQL支持多种索引类型,需根据查询场景选择。
-- 单列B-tree索引
CREATE INDEX idx_users_name ON users(last_name);
-- 复合B-tree索引(等值列在前,范围列在后)
CREATE INDEX idx_orders_user_date ON orders(user_id, order_date DESC);
CREATE INDEX idx_orders_order_no_hash ON orders USING HASH(order_no);
-- 全文检索索引
CREATE INDEX idx_docs_content_gin ON documents USING gin(to_tsvector('english', content));
-- JSONB索引
CREATE INDEX idx_orders_data_gin ON orders USING gin(data jsonb_path_ops);
-- 空间数据索引(PostGIS)
CREATE INDEX idx_places_geom_gist ON places USING gist(geom);
-- 模糊匹配索引
CREATE INDEX idx_users_name_trgm ON users USING gist(last_name gist_trgm_ops);
-- 时间序列索引
CREATE INDEX idx_sensor_data_time ON sensor_data USING brin(timestamp) WITH (pages_per_range = 32);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_user_status ON orders(user_id, status) INCLUDE (total_amount); -- INCLUDE避免回表
CREATE UNIQUE INDEX idx_users_username ON users(username);
CREATE INDEX CONCURRENTLY idx_users_phone ON users(phone);
\di+命令(psql)查看表的索引详情:\di+ users
SELECT * FROM pg_stat_user_indexes WHERE relname = 'users';
DROP INDEX IF EXISTS idx_users_old_email;
REINDEX INDEX idx_users_name; -- 重建单个索引
REINDEX TABLE users; -- 重建表的所有索引
CREATE INDEX idx_orders_user_status ON orders(user_id, status) INCLUDE (total_amount);
-- 查询时无需回表
SELECT user_id, status, total_amount FROM orders WHERE user_id = 1001 AND status = 'paid';
ANALYZE users;
pg_stat_user_indexes查看索引扫描次数,删除未使用的索引:SELECT * FROM pg_stat_user_indexes WHERE idx_scan = 0;
EXPLAIN ANALYZE查看查询是否使用了索引,识别性能瓶颈:EXPLAIN ANALYZE SELECT * FROM users WHERE username = 'john_doe';
若输出中包含Index Scan,则表示使用了索引;若为Seq Scan,则需优化索引或查询。