下面通过例子来看下二级聚集索引和普通二级索引在查询优化上的区别

  • 普通二级索引 查询使用了c2普通二级索引,但不是cover index

Cluster index用法

建表时指定cluster index

修改cluster index

  1. alter table t1 add clustering key(c3);

二级聚集索引相对普通二级索引,查询可以走cover index,可以省去二级索引回主键查数据的代价。对于MyRocks读能力不强的引擎来说,cover index显得尤为重要。

那么问题来了,如果我把表的所有列都建成一个普通二级索引,那么和二级聚集索引可以达到一样的效果,一样也可以使用cover index. 然而,二级索引有一些限制

  • MyRocks索引列总长度限制16K max_supported_key_length

另外,二级聚集索引性能更好

  • 全列普通二级索引key的长度较大,排序的开销更大
  • 全列普通二级索引在MyRocks中,数据都在key中,存储key时格式是memcomparable的,存取数据需encode/decode, 而二级聚集索引数据主要在value中,value中的数据不需要encode/decode

二级聚集索引更易维护

  • 对表的执行加减列操作后,全列普通二级索引需要重建,而二级聚集索引则不需要。

cluster index数据格式

  • 普通二级索引

MyRocks中普通二级索引对应的KV存储格式如下:

key由index_id,二级索引键和主键组成, 其中NULL-byte表示索引列是否为空。 value只有unpack_info,表示二级索引键和主键列转换为memcomparable格式的信息,如果不需要额外转换信息则unpace_info为null

  • 二级聚集索引

MyRocks中二级聚集索引对应的KV存储格式如下:

key: index_id,NULL-byte, 二级索引列, 主键列 value: unpack_info, 表中其他所有列

相对普通二级索引,value中还包括索引其他所有列的数据

由于二级聚集索引包含所有列信息,执行update语句更新非索引列时,二级聚集索引数据也需要更新。例如, t1表c2列为普通二级索引,c3列为二级聚集索引

  1. insert into t1 values(1,1,1,1);

总结

二级聚集索引是MyRocks表数据的一个完整copy, 结合MyRocks高压缩特性,这种冗余数据的方式在MyRocks上非常合适。二级聚集索引是MyRocks的一个重要feature,它能够让查询尽量走cover index,避免回表操作,提升了MyRocks的读能力。