GBASE南大通用技术分享:GBase 8a数据库索引机制解析之行存与列存索引原理差异
很多从行存数据库迁移过来的 DBA,习惯性地在 GBase 8a 建索引、靠索引来加速查询,却发现收效甚微甚至完全没有效果。这是因为列存引擎的数据访问模式与行存引擎根本不同,索引在列存环境下的角色和价值需要重新理解。本文从列存的物理存储结构出发,解释为什么列存不依赖传统 B-Tree 索引,南大通用GBase 8a数据库(gbase database) 实际使用了哪些替代机制,以及怎样在列存环境下做到真正有效的查询加速。
一、行存索引为什么在列存引擎里失效
要理解列存索引,必须先理解行存索引的工作原理,然后分析为什么同样的逻辑在列存引擎里行不通。
MySQL InnoDB 的 B-Tree 索引是一棵平衡树,叶子节点存储的是索引列的值和对应行的主键(或行地址)。当查询带有 WHERE customer_id = 10001 时,数据库沿 B-Tree 快速定位到 customer_id = 10001 对应的叶子节点,拿到行地址,然后按行地址从磁盘读取整行数据。这个过程的关键是"用索引定位行的位置,然后按行读取数据"。这套机制的前提是数据按行组织存储在磁盘上,知道行地址就能快速读出整行。
GBase 8a 的 Express 列存引擎完全改变了数据的物理存储方式:同一列的所有值连续存储在一起,形成若干个"列块(Column Block)"。当查询需要读取 customer_id 列时,只需要顺序读取这一列的数据块,完全不需要知道行在磁盘上的具体位置——因为列存本身就是按列连续存储的,顺序读取就是正确的访问模式。
在这种存储结构下,B-Tree 索引不仅没有帮助,反而可能有害。假设 customer_id 列有 B-Tree 索引,查询 WHERE customer_id = 10001 时,索引会指向满足条件的每一行的"行号",然后根据这些行号去各列的数据块中找对应位置的值。但列存数据块是为顺序读取优化的,按随机的行号跳跃读取反而会打破顺序访问模式,产生大量随机 I/O,性能比直接顺序扫描还差。这就是为什么"在列存引擎上建 B-Tree 索引"几乎没有意义。

浙公网安备 33010602011771号