在pg中,我们会经常使用索引来加速查询,但是在Greenplum中对于索引的依赖却比较低,应该合理的使用。因为在gp中顺序扫描会很快,而索引扫描则是一种随即搜索的模式。Greenplum的数据分布在Segment上,因此每个Segment会扫描全体数据的一小部分来得到结果。通过表分区,要扫描的数据量可能会更少,因此索引使用的场景可能会更少。
并且索引通常会增加一些数据库负担,它们使用存储空间并且在表被更新时需要被维护。
索引类型:
和pg不同,gp中仅支持btree和gist索引,同时在最新的Greenplum6.0版本又支持了gin和sp-gist索引。并且gp中支持了在pg中不支持的bitmap索引。
bitmap索引类似GIN倒排,只是bitmap的KEY是列的值,VALUE是BIT(每个BIT对应一行),而不是行号list或tree。
bitmap与btree一样,都支持 等于,大于,小于,大于等于,小于等于的查询。但是要注意:bitmap索引适用于只查询数据而不更新数据的数据仓库应用。
例子:
–建表
postgres=# CREATE table t2 (id int,info text)
postgres-# with(appendonly=true,orientation=column)
postgres-# distributed by(id);
CREATE TABLE
postgres=# insert into t2 select generate_series(1,100000),md5(random()::text);
INSERT 0 100000
–不使用索引
postgres=# EXPLAIN select * from t2 where id <10;
QUERY PLAN
---------------------------------------------------------------------------------
Gather Motion 2:1 (slice1; segments: 2) (cost=0.00..1364.00 rows=10 width=37)
-> Append-only Columnar Scan on t2 (cost=0.00..1364.00 rows=5 width=37)
Filter: id < 10
Optimizer status: legacy query optimizer
(4 rows)
–创建bitmap索引
postgres=# CREATE INDEX idx_t2 on t2 using bitmap(id);
CREATE INDEX
–再次查看执行计划
发现走bitmap索引扫描了。
postgres=# EXPLAIN select * from t2 where id <10;
QUERY PLAN
--------------------------------------------------------------------------------------------
Gather Motion 2:1 (slice1; segments: 2) (cost=101.98..808.90 rows=10 width=37)
-> Bitmap Append-Only Column-Oriented Scan on t2 (cost=101.98..808.90 rows=5 width=37)
Recheck Cond: id < 10
-> Bitmap Index Scan on idx_t2 (cost=0.00..101.98 rows=5 width=0)
Index Cond: id < 10
Optimizer status: legacy query optimizer
(6 rows)
重建索引:
–重建指定索引
postgres=# REINDEX INDEX idx_t2;
REINDEX
–重建一张表上所有索引
postgres=# REINDEX TABLE t2;
REINDEX