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 索引几乎没有意义。