二级索引 #

一、二级索引概述 #

1.1 什么是二级索引 #

二级索引允许在非主键列上进行高效查询。

text
二级索引工作原理:

表数据
┌─────────────────────────────────────────────────────────┐
│ user_id(PK) │ name    │ email              │ age       │
├─────────────────────────────────────────────────────────┤
│ uuid-001    │ 张三    │ zhang@example.com  │ 28        │
│ uuid-002    │ 李四    │ li@example.com     │ 32        │
│ uuid-003    │ 王五    │ wang@example.com   │ 25        │
└─────────────────────────────────────────────────────────┘

二级索引(email列)
┌─────────────────────────────────────────────────────────┐
│ email              │ user_id                            │
├─────────────────────────────────────────────────────────┤
│ li@example.com     │ uuid-002                           │
│ wang@example.com   │ uuid-003                           │
│ zhang@example.com  │ uuid-001                           │
└─────────────────────────────────────────────────────────┘

1.2 二级索引特点 #

text
二级索引特点:

优点
├── 支持非主键列查询
├── 自动维护
└── 创建简单

限制
├── 不适合高基数列
├── 不适合频繁更新列
├── 查询可能访问多个节点
└── 写入性能有开销

二、创建索引 #

2.1 基本创建 #

sql
-- 创建二级索引
CREATE INDEX users_email_idx ON users (email);

-- 使用IF NOT EXISTS
CREATE INDEX IF NOT EXISTS users_email_idx ON users (email);

2.2 索引命名 #

sql
-- 自动命名
CREATE INDEX ON users (email);
-- 索引名:users_email_idx

-- 自定义名称
CREATE INDEX email_search_idx ON users (email);

2.3 集合索引 #

sql
-- List索引
CREATE INDEX users_tags_idx ON users (tags);

-- Set索引
CREATE INDEX users_emails_idx ON users (emails);

-- Map键索引
CREATE INDEX users_prefs_keys_idx ON users (KEYS(preferences));

-- Map值索引
CREATE INDEX users_prefs_values_idx ON users (VALUES(preferences));

-- Map条目索引
CREATE INDEX users_prefs_entries_idx ON users (ENTRIES(preferences));

三、使用索引 #

3.1 基本查询 #

sql
-- 使用索引查询
SELECT * FROM users WHERE email = 'zhang@example.com';

-- 集合查询
SELECT * FROM users WHERE tags CONTAINS 'vip';
SELECT * FROM users WHERE preferences CONTAINS KEY 'theme';

3.2 索引选择 #

sql
-- Cassandra自动选择索引
-- 无需手动指定

-- 查看查询计划
TRACING ON;
SELECT * FROM users WHERE email = 'zhang@example.com';

四、索引限制 #

4.1 高基数问题 #

text
高基数问题:

高基数列
├── 如:UUID、时间戳
├── 索引表巨大
├── 查询效率低
└── 不适合建索引

低基数列
├── 如:状态、类型
├── 索引表小
├── 查询效率高
└── 适合建索引

4.2 适用场景 #

text
二级索引适用场景:

适合
├── 低基数列(状态、类型)
├── 查询频率高
├── 更新频率低
└── 表数据量适中

不适合
├── 高基数列(UUID、时间戳)
├── 频繁更新
├── 大表
└── 需要范围查询

4.3 性能考虑 #

text
性能考虑:

写入性能
├── 每次写入需更新索引
├── 索引越多,写入越慢
└── 控制索引数量

查询性能
├── 可能需要访问多个节点
├── 高基数列查询慢
└── 考虑物化视图替代

五、删除索引 #

5.1 删除语法 #

sql
-- 删除索引
DROP INDEX users_email_idx;

-- 使用IF EXISTS
DROP INDEX IF EXISTS users_email_idx;

5.2 删除影响 #

text
删除索引影响:

立即生效
├── 索引数据删除
├── 相关查询需要ALLOW FILTERING
└── 写入性能提升

六、索引最佳实践 #

6.1 设计建议 #

text
索引设计建议:

1. 选择合适的列
   └── 低基数、查询频繁

2. 控制索引数量
   └── 每表不超过2-3个

3. 监控性能
   └── 关注查询和写入性能

4. 考虑替代方案
   └── 物化视图、反范式化

6.2 替代方案 #

sql
-- 替代方案1:物化视图
CREATE MATERIALIZED VIEW users_by_email AS
SELECT * FROM users
WHERE email IS NOT NULL
PRIMARY KEY (email, user_id);

-- 替代方案2:反范式化表
CREATE TABLE users_by_email (
    email TEXT PRIMARY KEY,
    user_id UUID,
    name TEXT
);

七、总结 #

二级索引要点:

  1. 适用场景:低基数列、查询频繁
  2. 创建简单:CREATE INDEX语法
  3. 自动维护:写入时自动更新
  4. 性能开销:影响写入性能
  5. 限制明确:不适合高基数列
  6. 替代方案:物化视图、反范式化

下一步,让我们学习SASI索引!

最后更新:2026-03-27