二级索引与视图原理: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/
desc tables;
# 查看表结构
describe demojie.user;
# 在表 user 的 name 字段上创建索引
# 注意:索引名称必须在当前 Keyspace 唯一
CREATE INDEX name_index ON demojie.user (name);
# 注意:删除的时候不需要指定表名
DROP INDEX demojie.name_index;
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
- 视图的更新是异步的