SQL映射到kv的粒度和性能的关系

您好, TiDB是把一行映射成一个KV, 粒度会比较大, CockroachDB是把一个cell映射成一个kv, 粒度比较小, 粒度越大可能scan性能越好, 但更新时可能有rmw, 粒度越小, 越灵活, 更新少数列时性能更好, 但scan会差吧. 这之间的tradeoff时怎么考虑的呢? 谢谢!

这个还涉及到元数据吧
比如你定义了 N 个属性,然后每个属性之间肯定还有先后次序,
如果按 row 存储,只需要考虑 主键标识 和 索引的关系,就可以快速的获取到这一行数据,通过元数据的映射就可以转换成 SQL
如果按照 每个属性存储,需要考虑到属性之间的顺序,然后属性和实际值之间的映射关系,然后最后需要考虑 主键标识 和 索引的关系

rmw 是什么描述?
如果你对列存比较有兴趣,可以关注下 tiflash

1赞

如果粒度变小, 肯定会更复杂, 放置顺序和映射需要更多的考虑, 但可能会更接近列存的特性, 比如可以有单列scan, 还可以支持一定的store层的project算子?
RMW是read-modify-write, 如果只更新一行的少数几列的话, 无需读上原来的一行, 直接put新的列值就可以了, 不需要像row一样首先需要一次额外的随机读, 然后更新几列组装起来, 再写回去.
但有的update是需要先读原来的值, 这种可能也还好.

这个理解上有点误区吧, LSM Tree 本身就是只有 insert, 也不存在 RMW 的问题(可能会有写放大和读放大的问题)

建议你先了解下 tidb 的结构,以及 tikv 数据读写的模式

我的意思是上层意义上的RMW, 不是lsm tree自己, 比如你要update一列, 但是你是row存储, 你put到tikv的得是完整的一行吧(除非用了merge算子), 这时候你得先读上来再更新这一行中的这一列组装好然后写下去; 而如果是列分开的, 那我直接put这一列的新值不就可以了?

嗯,没有上层的概念 :grinning:

数据一定要落地

我看crdb提到了这个问题, 但他们现在也不用rocksdb了, 也不再用纯粹的单cell存储了, 而是更灵活点.

每个产品适用的场景不太一样,看你更关注什么了

是的, 谢谢你的回复!