SELECT COUNT(*) FROM app.cf_track;
ANALYZE app.cf_track; -- 更新统计信息
步骤 2:无业务索引时看 slug 查询
若存在旧索引先记下名字;对比用:
-- 可能已有 UNIQUE 约束自带索引;用 EXPLAIN 观察即可
EXPLAIN
SELECT id, title FROM app.cf_track
WHERE slug = 'sql-essentials';
有唯一约束时,通常已是 Index Scan / Index Only Scan。这正好说明:主键/唯一约束会自动带索引。
步骤 3:联合索引与范围
CREATE INDEX IF NOT EXISTS idx_track_cat_sort
ON app.cf_track (category, sort_order);
EXPLAIN ANALYZE
SELECT id, title FROM app.cf_track
WHERE category = 'language' AND sort_order < 100;
关注:
是否出现 Index Scan 或 Bitmap Index Scan using idx_track_cat_sort
rows 估算与实际(ANALYZE 时)差距
前缀原则:条件只有 sort_order 而没有 category 时,该联合索引往往用不上——与 MySQL 类似。
步骤 4:GIN 服务 JSONB
CREATE INDEX IF NOT EXISTS idx_track_meta_gin
ON app.cf_track USING GIN (metadata);
EXPLAIN
SELECT slug FROM app.cf_track
WHERE metadata @> '{"featured": true}'::jsonb;
再对比等值:
EXPLAIN
SELECT slug FROM app.cf_track WHERE slug = 'postgresql-essentials';
后者应走 B-tree(唯一索引),不要幻想一个 GIN 包打天下。
步骤 5:读计划关键词
EXPLAIN (ANALYZE, BUFFERS)
SELECT id, title FROM app.cf_track
WHERE category = 'language' AND sort_order < 100;