索引是數據庫中預構建的數據結構,用于加速數據檢索。其核心作用是將全表掃描(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
,則需優化索引或查詢。