Greenplum 最佳实践 - 什么时候选择bitmap索引

本文详细介绍了位图索引的工作原理及其在PostgreSQL和Greenplum数据库中的应用。位图索引适用于数据仓库场景,尤其是当列具有100到10万个不同值时。文章还探讨了位图索引的优势、限制以及最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

标签

PostgreSQL , Greenplum , bitmap index


背景

PostgreSQL 目前支持8种索引接口,包括B-Tree, hash, gin, gist, sp-gist, brin, rum, bloom。

Greenplum 目前支持B-Tree, GiST, bitmap三种索引接口。

用户可以根据不同的数据类型,不同的请求类型,使用不同的索引接口建立相应的索引。例如对于数组,全文检索类型,可以使用GIN索引,对于地理位置数据,范围数据类型,图像特征值数据,几何类数据等,可以选择GiST索引。

PG的八种索引的介绍,可以参考bruce写的index internal、源码以及如下文档

http://leopard.in.ua/2015/04/13/postgresql-indexes#.WRHHH_mGOiQ

bitmap index 原理

如图所示,bitmap索引将每个被索引的VALUE作为KEY,使用每个BIT表示一行,当这行中包含这个VALUE时,设置为1,否则设置为0。

pic

如何从bitmap 索引检索数据,并查找到对应HEAP表的记录呢?

必须要有一个mapping 转换功能(函数),才能将BIT位翻译为行号。例如第一个BIT代表第一行,。。。以此类推。(当然了,mapping函数没有这么简单,还有很多优化技巧)

bitmap 的优化技术举例,比如

1. 压缩

例如连续的0或1可以被压缩,具体可以参考WIKI里面关于BITMAP的压缩算法,算法也是比较多的。

2. 分段或分段压缩

例如,每个数据块作为一个分段,每个分段内,记录这个数据块中的VALU对应的BIT信息。

3. 排序

排序是为了更好的进行压缩,例如堆表按被索引的列进行排序后,每个VALUE对应的行号就都是连续的了,压缩比很高。

另外用户也可以参考一下roaring bitmap这个位图库,应用非常广泛,效果也很不错。

https://github.com/zeromax007/gpdb-roaringbitmap

https://github.com/RoaringBitmap/CRoaring

bitmap index 适合什么场景

从bitmap index的结构我们了解到,被索引的列上面,每一个value都分别对应一个BIT串,BIT串的长度是记录数,每个BIT代表一行,1表示该行存在这个值,0表示该行不存在这个值。

因此bitmap index索引的列,不能有太多的VALUE,最好是100到10万个VALUE,也就是说,这样的表的BITMAP索引有100到10万条BIT串。

当我们对这个表的这个字段进行类似这样的查询时,效率就非常高。

select * from table where col = a and col = b and col2=xxx;        
-- a,b的bit串进行BITAND的操作,然后再和col2=xxx的BIT进行BITAND操作,返回BIT位为1的,使用bitmap function返回行号,取记录。      
      
select count(*) from table where col = a and col = b and col2=xxx;        
-- a,b的bit串进行BITAND的操作,然后再和col2=xxx的BIT进行BITAND操作,返回BIT位为1的,使用bitmap function返回行号,取记录,算count(*)。      

1. 适合有少量不重复值的列 。

2. 适合多个条件的查询,条件越多,bit and,or 的操作过滤掉的数据就越多,返回结果集越少。

bitmap index 不适合什么场景

由于每个VALUE都要记录每行的BIT位,所以如果有1亿条记录,那么每个VALUE的BIT串长度就是1亿。如果有100万个不同的VALUE,那么BITMAP INDEX就有100万个长度为1亿的bit串。

1. 不适合有太多不重复值的表字段。

3. 同样,也不适合有太少不重复值的列,例如男女。这样的列,除非可以和其他列组合赛选出很少量的结果集,否则返回的结果集是非常庞大的,也是不适合的。

3. 不适合频繁的更新,因为更新可能带来行迁移,以及VALUE的变化。如果是行迁移,需要更新整个bitmap串。如果是VALUE变化,则需要修改整个与变化相关的VALUE的BIT串。

greenplum bitmap index手册

About Bitmap Indexes

Greenplum Database provides the Bitmap index type.
Bitmap indexes are best suited to data warehousing applications and decision support systems with large amounts of data, many ad hoc queries, and few data modification (DML) transactions.

An index provides pointers to the rows in a table that contain a given key value.
A regular index stores a list of tuple IDs for each key corresponding to the rows with that key value.
Bitmap indexes store a bitmap for each key value. Regular indexes can be several times larger than the data in the table,
but bitmap indexes provide the same functionality as a regular index and use a fraction of the size of the indexed data.

Each bit in the bitmap corresponds to a possible tuple ID. If the bit is set, the row with the corresponding tuple ID contains the key value.
A mapping function converts the bit position to a tuple ID. Bitmaps are compressed for storage.
If the number of distinct key values is small, bitmap indexes are much smaller, compress better,
and save considerable space compared with a regular index.
The size of a bitmap index is proportional to the number of rows in the table times the number of distinct values in the indexed column.

Bitmap indexes are most effective for queries that contain multiple conditions in the WHERE clause.
Rows that satisfy some, but not all, conditions are filtered out before the table is accessed.
This improves response time, often dramatically.

When to Use Bitmap Indexes

Bitmap indexes are best suited to data warehousing applications where users query the data rather than update it.
Bitmap indexes perform best for columns that have between 100 and 100,000 distinct values and when the indexed column is often queried in conjunction with other indexed columns.
Columns with fewer than 100 distinct values, such as a gender column with two distinct values (male and female),
usually do not benefit much from any type of index.
On a column with more than 100,000 distinct values, the performance and space efficiency of a bitmap index decline.

Bitmap indexes can improve query performance for ad hoc queries.
AND and OR conditions in the WHERE clause of a query can be resolved quickly by performing the corresponding Boolean operations directly on the bitmaps before converting the resulting bitmap to tuple ids.
If the resulting number of rows is small, the query can be answered quickly without resorting to a full table scan.

When Not to Use Bitmap Indexes

Do not use bitmap indexes for unique columns or columns with high cardinality data,
such as customer names or phone numbers.
The performance gains and disk space advantages of bitmap indexes start to diminish on columns with 100,000 or more unique values,
regardless of the number of rows in the table.

Bitmap indexes are not suitable for OLTP applications with large numbers of concurrent transactions modifying the data.

Use bitmap indexes sparingly. Test and compare query performance with and without an index.
Add an index only if query performance improves with indexed columns.

greenplum中如何创建bitmap index

CREATE INDEX title_bmp_idx ON films USING bitmap (title);    

bitmap 在PG数据库中的应用

在PostgreSQL中虽然没有bitmap索引,但是多个条件的查询,支持自动生成BIT,并通过BitmapAnd, BitmapOr操作,计算并合并结果。

PostgreSQL is not provide persistent bitmap index.

But it can be used in database to combine multiple indexes.

PostgreSQL scans each needed index and prepares a bitmap in memory giving the
locations of table rows that are reported as matching that index’s conditions.

The bitmaps are then ANDed and ORed together as needed by the query.

Finally, the actual table rows are visited and returned.

bitmap 的其他应用

bitmap在阿里云RDS PG中进行了扩展,支持更多的BIT操作,用户可以通过varbit来维护自己业务数据相关的BIT索引(字段),例如用户画像系统,铁路售票系统,门禁广告系统等。

《阿里云RDS for PostgreSQL varbitx插件与实时画像应用场景介绍》

《基于 阿里云 RDS PostgreSQL 打造实时用户画像推荐系统》

《PostgreSQL 与 12306 抢火车票的思考》

《门禁广告销售系统需求剖析 与 PostgreSQL数据库实现》

另外,roaring bitmap也可以作为一种数据类型,植入到PG中。

https://github.com/zeromax007/gpdb-roaringbitmap

参考

https://gpdb.docs.pivotal.io/4390/admin_guide/ddl/ddl-index.html#topic93

http://leopard.in.ua/2015/04/13/postgresql-indexes#.WRHHH_mGOiQ

《阿里云RDS for PostgreSQL varbitx插件与实时画像应用场景介绍》

《基于 阿里云 RDS PostgreSQL 打造实时用户画像推荐系统》

https://github.com/zeromax007/gpdb-roaringbitmap

<think>我们正在解决Greenplum初始化过程中出现的符号链接错误:"Too manylevels ofsymbolic links"这个错误通常发生在数据目录路径中存在循环符号链接或者符号链接嵌套过深(超过系统限制)的情况。解决步骤:1. **检查数据目录配置**:在初始化配置文件(如:`gp_init_config`)中,检查以下配置项:- `declare-aDATA_DIRECTORY`:定义每个segment的数据目录-`MASTER_DIRECTORY`:master的数据目录- `MASTER_DATA_DIRECTORY`:实际用于存储master数据的目录(通常与MASTER_DIRECTORY相同或不同)确保这些目录路径是真实存在的物理路径(非符号链接),或者符号链接的深度不超过系统限制(一般不超过40层)。2.**验证符号链接**:在计划作为数据目录的路径上,使用`readlink-f <路径>`来解析符号链接,并检查是否有循环或嵌套过深。例如:```bashreadlink-f/data/primary1```3.**修复方法**:如果发现数据目录配置了符号链接,并且嵌套过深,有两种解决方案:a)将符号链接替换为实际路径(物理路径)-在配置文件中直接使用物理路径b)重新创建符号链接,确保没有循环且层数合理-使用绝对路径创建符号链接,避免相对路径导致的嵌套4. **检查系统限制**:虽然Linux系统通常支持40层符号链接,但可以通过以下命令查看当前系统的限制:```bashcat /proc/sys/fs/symlink```注意:这个文件可能不存在,因为Linux内核通常不提供这个参数(实际限制在40层,且不可配置)。所以重点应放在避免循环符号链接。5. **具体错误案例**:例如,配置文件中指定了:```bashdeclare -a DATA_DIRECTORY=(/home/gpadmin/primary /home/gpadmin/primary)```而`/home/gpadmin/primary`是一个指向自身的符号链接:```bash$ls -l /home/gpadmin/primarylrwxrwxrwx .../home/gpadmin/primary-> /home/gpadmin/primary```这会导致循环,从而出现错误。6. **修复步骤示例**:假设发现`/data/primary1`是一个符号链接,且指向了一个多层嵌套的路径,我们可以:a)删除该符号链接,并创建实际目录:```bashrm /data/primary1mkdir/data/primary1```b)或者修改符号链接,使其直接指向一个物理路径(且该路径没有多层符号链接):```bashln -sfn/physical/path/to/dir /data/primary1```7.**重新初始化**:修复后,重新运行`gpinitsystem`命令。8.**预防措施**:在初始化前,使用`gpcheck`(Greenplum提供的工具)进行环境检查,确保文件系统配置正确。引用说明:-关于符号链接的限制,参考Linux内核文档[^1]。-Greenplum官方文档中关于数据目录配置的要求[^2]。注意:在分布式系统中,每个节点上的数据目录路径都需要检查,因为错误可能发生在任意一个节点上。相关问题:1.如何检查Greenplum集群中所有节点的目录是否存在?2. Greenplum初始化过程中还有哪些常见的文件系统错误?3.如何配置Greenplum的数据目录以实现最佳性能?我们将按照上述步骤进行详细说明。</think>### Greenplum 初始化遇到符号链接错误的解决方案 当执行 `gpinitsystem` 时出现 **"Too many levels of symbolic links"** 错误,表明数据目录路径中存在循环符号链接或嵌套层级超过系统限制(Linux 默认限制为 40 层)。以下是系统级排查和修复步骤: #### 诊断步骤 1. **检查符号链接深度** 在涉及节点上运行: ```bash # 检查 Master 目录 readlink -f $MASTER_DATA_DIRECTORY | wc -c # 检查 Segment 目录(示例) readlink -f /data/primary/gpseg0 | wc -c ``` 若输出值 > 1000(路径字符数)或层级显示异常,说明符号链接嵌套过深。 2. **检测循环链接** 使用 `namei` 命令解析路径: ```bash namei -l $MASTER_DATA_DIRECTORY ``` 输出中若出现重复路径(如 `A -> B -> C -> A`),即存在循环符号链接。 #### 修复方案 1. **替换符号链接为物理路径** 修改初始化配置文件 `gp_init_config`: ```diff - declare -a DATA_DIRECTORY=(/symlink_path/primary) + declare -a DATA_DIRECTORY=(/physical_disk/primary) # 使用物理路径 - MASTER_DIRECTORY=/symlink_path/master + MASTER_DIRECTORY=/physical_disk/master # 使用物理路径 ``` 2. **简化符号链接结构** 若必须使用符号链接: ```bash # 删除旧链接 rm /data/primary # 创建直接指向物理路径的链接(最多1层) ln -s /physical_disk/primary /data/primary ``` 3. **验证所有节点路径一致性** 在集群每个节点执行: ```bash gpssh -f hostfile.txt "ls -ld /data/primary" ``` 确保所有节点路径解析结果相同。 #### 关键配置检查 1. **权限修复** 确保物理路径权限正确: ```bash chown -R gpadmin:gpadmin /physical_disk chmod 755 /physical_disk ``` 2. **环境变量修正** 检查 `$MASTER_DATA_DIRECTORY` 是否指向符号链接: ```bash echo $MASTER_DATA_DIRECTORY | grep -q '->' && echo "符号链接存在!" ``` 若存在,在 `.bashrc` 中修改为物理路径。 > **原理说明**:Greenplum 在初始化时需要精确解析物理存储位置。符号链接嵌套会导致路径解析失败,尤其当跨节点路径不一致时[^1]。Linux 内核限制符号链接递归解析深度为 40 层(可通过 `cat /proc/sys/fs/symlink` 验证)[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值