二级索引与视图原理:https://www.cnblogs.com/stoneFang/p/6715289.html

二级索引:主键是一级索引,所以其他列就是二级索引

  • 二级索引是与每个节点保存在一起的
  • 按理来说,如果需要查询某个 key 的二级索引,需要对所有节点发起查询。效率很低
  • 优化:循环查询时,每一轮会根据 CONCURRENCY_FACTOR 来觉得有多少个节点会被查询。如果返回的数据不够,则 FACTORY + 1,直至返回的结果集够了
  • C* 是根据 token range 来查询这些节点的,所以返回的结果集没有特定的顺序

总体来说,索引的效率还是很低的,除非能带上主键列,走节点上的本地二级索引。

二级索引:中间本地表

https://www.yiibai.com/cassandra/cassandra-create-index.html
Cassandra 的查询必须使用主键,否则数据量一大,就会查询超时,除非使用 Allow Filtering 扫描全表。
Cassandra 的索引其实是创建了隐藏表,使用索引主键指向原始主键,索引数据原始数据是在同一个节点上的

详情:https://www.flyml.net/2016/10/30/cassandra-tutorial-materialized-view/

  1. desc tables;
  2. # 查看表结构
  3. describe demojie.user;
  4. # 在表 user 的 name 字段上创建索引
  5. # 注意:索引名称必须在当前 Keyspace 唯一
  6. CREATE INDEX name_index ON demojie.user (name);
  7. # 注意:删除的时候不需要指定表名
  8. DROP INDEX demojie.name_index;
  9. DROP INDEX IF EXISTS KeyspaceName.IndexName;

创建表:

CREATE TABLE student(  
   student_id int PRIMARY KEY,  
   student_name text,  
   student_city text,  
   student_fees varint,  
   student_phone varint  
);

视图:实际表

物化视图:MySQL 的视图是虚拟表,而 Cassandra 的 MV 是存储着真实的数据,因此成为物化。

  • 视图的数据与基表的数据并不是在同一个节点上,基于视图的查询相等于对另外一张表的查询

视图的修改流程:https://developer.aliyun.com/article/705400

  • update user set name=’a’ where id=1 -> Replication Factor 个节点
  • 每个副本在本地上锁,然后先 select
  • 然后先创建本地的 BatchLog:delete 和 insert
  • 再通过异步发送 BatchLog 给 View 的目标节点,CL=ONE
  • 之后本地再对基表进行修改 mutation
  • 然后响应给客户端

创建视图,MV 的第二个主键要指向原表主键:

CREATE MATERIALIZED VIEW user_by_email AS
  SELECT * FROM user
  WHERE email IS NOT NULL
PRIMARY KEY (email, username);

MV 性能总结:

  • 从 MV 读取数据跟从原始表读数据的性能是一样的
  • 写数据的时候,每一个 MV 性能会下降10%
  • 如果 Primary Key 只有 1 个,MV 的性能要好于人工反范式
  • 对于复合主键(Compund primary keys),MV 相对来说还是要快的,但是当复合主键太长(比如>100)的时候,人工可能还要快一些
  • 如果原始表大规模删除,MV 需要发起很多 CQL 来查询与删除。性能可能会急剧下降
  • MV 主键的设计还是要考虑是否会造成热点(hot spot),hot spot 依然会造成性能问题,甚至 OOM
  • 视图的更新是异步的