作者:崔鹏
索引概述与类型
1、索引概述
系统会在表更新时更新索引,而且会在它觉得使用索引比顺序扫描表效率更高时使用索引
我们可能需要定期地运行ANALYZE命令来更新统计信息以便查询规划器能做出正确的决定
索引也会使带有搜索条件的UPDATE和DELETE命令受益;此外索引还可以在连接搜索中使用
并发构建索引允许并行的写,但是有些警告需要注意
一个索引被创建后,系统必须保持它与表同步。这增加了数据操作的负担
那些很少或从不在查询中使用的索引应该被移除。
2、索引类型
PostgreSQL提供了多种索引类型,主要的四种:B-Tree、Hash、GiST和GIN
每种索引使用了不同的算法,都有其适合的查询类型
缺省时,CREATE INDEX命令将创建B-Tree索引
索引的分类及详解
1、B-tree 索引
B-Tree索引是标准的索引类型,B代表平衡,主要用于等于和范围查询,具体使用场景:
当索引列包含操作符" <、<=、=、>=和>"作为查询条件时
在使用BETWEEN、IN、IS NULL和IS NOT NULL的查询中
基于模式匹配操作符的查询,仅当模式存在一个常量,且该常量位于模式字符串的开头时
默认情况下,B-tree索引将它的项以升序方式存储,并将空值放在最后
在创建B-tree索引时,通过ASC、DESC、NULLS FIRST和NULLS LAST选项来改变索引的排序
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST); CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
2、Hash索引
散列(Hash)索引只能处理简单的等于比较
当索引列使用等于操作符进行比较时,查询规划器会考虑使用散列索引
PostgreSQL散列索引的性能不比B-Tree索引强,但是散列索引的尺寸和构造时间则更差
散列索引操作目前没有记录WAL日志,发生了DB崩溃,需用REINDEX重建散列索引
CREATE INDEX name ON table USING hash (column);
3、GiST
GiST索引不是一种单独的索引类型,更像一种架构
GiST(通用搜索树)提供了一种用于存储数据的方式来构建平衡的树结构
可以在该架构上实现很多不同的索引策略
可以使GiST索引根据不同的索引策略,使用特定的操作符类型
二维几何类型的以下操作符支持通过Gist索引访问
<< --严格在左侧,例如circle’((0,0),1)’ << circle’((5,0),1)’ &< --表示左边的平面体不会扩展到超过右边的平面体的右边. 例如box '((0,0),(1,1))' &< box '((0,0),(2,2))’ &> --表示左边的平面体不会扩展到超过右边的平面体的左边. 例如box '((0,0),(3,3))' &> box '((0,0),(2,2))’ >> -- 严格在右 <<| --严格在下 &<| --不会扩展到超出上面 |&> --不会扩展到超出下面 |>> -- 严格在上 @> --包含 <@ --被包含 ~= --相同 && --相交
4、SP-GisST
SP-GisST与Gist类似,也是一种索引框架
支持基于磁盘存储的非平衡数据结构如四叉树,k-d树,radix树
例如二维的point类型,Sp-Gist索引支持的操作符如下: • << • >> • ~= • <@ • <^ -- 在下面, circle '((0,0),1)' <^ circle '((0,5),1)’ • >^ -- 在上面, circle '((0,5),1)' >^ circle '((0,0),1)'
5、GIN
GIN索引是“倒排索引”,它可以处理包含多个键的值(比如数组)
与GiST类似,GIN可以支持多种不同的用户定义的索引策略和特定操作符
可以使GIN索引根据不同的索引策略,使用特定的操作符类型
作为示例,PostgreSQL的标准发布中包含了用于一维数组的GIN操作符类型
6、多列索引
PostgreSQL中的索引可以定义在数据表的多个字段上
CREATE TABLE test2 (major int, minor int,name varchar); CREATE INDEX test2_mm_idx ON test2 (major, minor);
目前,只有B-tree、GiST、GIN 和 BRIN 支持多列索引,其中最多可以声明32个字段
使用多列索引需要谨慎
多列索引类型 |
使用说明 |
B-Tree |
该索引字段的任意子集均可用于查询条件,但只有多列合索引中的第一个索引字段(最左边)被包含其中时,才可以获得最高效率。 |
GiST |
只有当第一个索引字段被包含在查询条件中时,才能决定该查询会扫描多少索引数据,而其他索引字段上的条件只是会限制索引返回的条目。 假如第一个索引字段上的大多数数据都有相同的键值,那么此时应用GiST索引就会比较低效。 |
GIN |
GIN复合索引不会受到查询条件中使用了哪些索引字段子集的影响,无论是哪种组合,都会得到相同的效率。 |
8、唯一索引
只有B-Tree索引可以被声明为唯一索引
如果索引声明为唯一索引,就不允许出现多个索引值相同的行(NULL值相互间不相等)
CREATE UNIQUE INDEX name ON table (column [, ...]);
9、表达式索引
例:SELECT * FROM test1 WHERE lower(col1) = 'value';
解决办法:CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
10、函数索引
Access Method(B-tree,Hash,GiST,SP-GiST,GIN)
使用的operator class,以及opc中定义的operator或function
还需要符合当前配置的Planner配置
索引的成本跟哪些参数相关:
#random_page_cost = 4.0——随机页面扫描
#cpu_index_tuple_cost = 0.005——索引扫描带来的索引的tuple的开销
#effective_cache_size = 128MB——数值越大越倾向走索引扫描,因为数值越大数据可能都在OS cache里面,它的随机页面的成本就降低了
点击加载更多