在 PostgreSQL 的世界里,索引有好几种,每种都有自己的独特作用。就像选交通工具一样:你可以骑自行车去公园,但要穿越城市,大概率还是选汽车。不同的索引就适合不同的场景。
PostgreSQL 里主要的索引类型有:
B-TREE索引:大多数场景下的万能索引。HASH索引:专门为精确匹配优化。GIN索引:查数组和 JSONB 超好用。GiST索引:搞复杂数据类型,比如地理信息用的。
索引就是为了加快查找行的速度。它们有 4 种不同的优化方式:每种类型都能加速特定的操作,适合特定的数据类型。
你其实没法直接操作索引。你能做的,就是选个索引类型:要么不用,要么用上面这些。我们现在就一个个聊聊它们,看看啥时候用、怎么用。
B-TREE 索引
B-TREE(全称 "balanced tree")是最常见的索引类型,也是 PostgreSQL 的基础。它会建一个树形结构,把数据组织得很有序,查找、排序、过滤都很快。
想象一下图书馆的书架,每个架子上的书都按字母顺序排好。你要找“M”开头的书,不用一本本翻,直接从中间开始找就行。平衡树也是类似的原理。
啥时候用?
几乎随时都能用!B-TREE 索引特别适合:
- 区间查找:
WHERE price > 100。 - 排序:
ORDER BY name ASC。 - 等值查找:
WHERE id = 42。
举个创建的例子:
-- 给 products 表的 price 列建个 B-TREE 索引:
CREATE INDEX idx_price ON products(price);
以后你写 WHERE price > 100 这种查询,PostgreSQL 就能用这个索引,省得全表扫描了。
HASH 索引
HASH 索引用哈希表来加速查找。它的强项就是精确匹配。但 HASH 索引有个限制:不支持区间查找和排序。
就像卡片柜,每张卡片都有编号。你要找 42 号卡,管理员立马给你。但你要说:“给我 40 到 50 号的卡”,那就没戏了。
HASH 索引只适合精确查找:
WHERE email = 'user@example.com'。SELECT ... WHERE id = 123。
要查区间或排序,HASH 就不行了。
创建例子:
-- 给 users 表的 email 列建个哈希索引:
CREATE INDEX idx_email_hash ON users USING HASH (email);
以后 PostgreSQL 查 WHERE email = 'user@example.com' 这种就会用这个索引。
注意:HASH 索引只适合特定场景,用得比 B-TREE 少。
GIN 索引(Generalized Inverted Index)
GIN 是专门搞数组、JSONB 和文本数据的索引,简直有点魔法的感觉。想象你有个柜子,里面有成千上万个抽屉,每个抽屉都贴着标签。比如“苹果”抽屉里全是苹果,“香蕉”抽屉里全是香蕉。你要找苹果或香蕉,直接去对应抽屉就行,根本不用全翻一遍。
GIN 索引适合:
- 查数组:
@>(包含)、<@(被包含)。 - JSONB 数据:
WHERE jsonb_data @> '{"key": "value"}'。
创建例子
-- 给 products 表的 tags(数组)列建个 GIN 索引:
CREATE INDEX idx_tags_gin ON products USING GIN (tags);
这样 PostgreSQL 查找标签比如“电子产品”和“推荐”时就很快了。
GiST 索引(Generalized Search Tree)
GiST 索引是处理更复杂数据类型的利器,比如地理坐标和区间。它会建树,专门优化空间查找和区间查找。
想象一张城市地图,每个点都按坐标标出来。你要找离你 5 公里内的所有点,查起来就很快。
GiST 适合:
- 地理数据:
SELECT ... FROM locations WHERE ST_DWithin(geom, point, distance)。 - 区间查找:
WHERE date_range && '[2023-01-01, 2023-12-31]'。
例子:
-- 给 places 表的 location(地理数据)列建个 GiST 索引:
CREATE INDEX idx_location_gist ON places USING GiST (location);
这样就能做各种复杂的地理查询,比如查最近的点啥的。
索引类型对比表
| 索引类型 | 适合场景... | 使用例子 | 备注 |
|---|---|---|---|
B-TREE |
区间查找、排序 | price > 100、ORDER BY name ASC |
万能索引。 |
HASH |
精确等值判断 | email = 'user@example.com'、id = 42 |
不支持区间。 |
GIN |
数组、JSONB | tags @> '{tech}'、jsonb_data @> '{"key": "value"}' |
复杂数据更快。 |
GiST |
地理、区间、距离 | ST_DWithin(geom, point, distance) |
搞地理数据用。 |
现在你已经了解 PostgreSQL 里主要的索引类型和用法了。记住:选索引就是个策略活,直接影响你查询的速度。下棋要有策略,别让慢查询拖你后腿!
GO TO FULL VERSION