1. 主键索引(Primary Key Index)
-
原理: 主键索引基于数据的物理排序存储。在StarRocks中,定义了主键的表,其数据将会按照主键字段的值进行有序排列。这不仅提供了唯一性约束,还确保了基于主键的查询能够通过跳跃列表或类似的数据结构快速定位记录。
-
案例: 假设有一个用户行为表
user_action
,其主键定义为(user_id, action_time)
,这意味着StarRocks会自动为主键字段创建索引,并按照这两个字段的组合进行排序存储。当执行如下的查询时,主键索引能高效工作:
-- 创建表时指定主键 CREATE TABLE user_data ( user_id INT NOT NULL, name STRING, gender ENUM('Male', 'Female'), registration_date DATE, PRIMARY KEY (user_id) ) ENGINE=OLAP DUPLICATE KEY(user_id) DISTRIBUTED BY HASH(user_id) BUCKETS 100;
SELECT * FROM user_data WHERE user_id = 123;
2. 前缀索引(Prefix Index / ShortKey Index)
-
原理: 对于复合键的一部分或者字符串类型列的前几个字符,可以创建前缀索引以减少索引空间占用并优化某些查询。例如,对一个长字符串的前N个字符建立索引,可用于匹配开头的部分关键字。
-
案例: 如果表的排序键是
(country_code, user_id)
,并且country_code
是一个低基数列(如国家代码),则StarRocks会自动构建前缀索引。当查询涉及country_code
时,例如:
SELECT * FROM user_table WHERE country_code = 'CN';
-- 案例: 假设有一个手机号码列 phone_number,并且经常按区号进行查询,可以创建前缀索引: CREATE TABLE users ( ... phone_number VARCHAR(20), INDEX idx_phone_number (phone_number(7)) -- 前7位区号索引 );
-- 使用前缀索引案例 SELECT * FROM users WHERE phone_number LIKE '010%';
3. Bitmap 索引
-
原理: Bitmap索引特别适用于高度离散且基数较低的列,如性别、地区等类别属性。它将每个独特的值映射到一个位图上,其中每一位代表一行数据是否包含该值。当多个位图需要进行交集、并集等操作时,只需对位图进行逻辑运算,从而实现高效的集合运算查询。
-
案例: 假设有一个性别列
gender
,且它的值只有两个状态(男/女)。若要快速统计男女用户数量,可以为gender
列创建 Bitmap 索引。查询如下:
CREATE BITMAP INDEX idx_gender ON example_table(gender);
SELECT COUNT(*) FROM user_data WHERE gender = 'Female';
4. Bloomfilter 索引
-
案例: 在高基数列(如订单ID)上使用Bloomfilter索引可以帮助快速排除那些肯定不存在所查找值的数据块,减少不必要的数据读取。例如:
- 假设我们有一个名为
users
的表,其中包含id
和name
两个字段,我们想在id
字段上创建一个布隆过滤器:
CREATE TABLE users ( id BIGINT COMMENT '用户ID', name STRING COMMENT '用户名' ) ENGINE=OLAP DUPLICATE KEY(id) COMMENT '用户表' PROPERTIES ( "bloom_filter_columns" = "id" );
-- 向 users 表中插入一些数据: INSERT INTO users (id, name) VALUES (1, 'Alice'); INSERT INTO users (id, name) VALUES (2, 'Bob'); INSERT INTO users (id, name) VALUES (3, 'Charlie');
SELECT * FROM users WHERE id = 4;
由于我们在 id
字段上创建了布隆过滤器,StarRocks 可以先检查布隆过滤器来判断 id
为 4 的记录是否可能不存在。如果布隆过滤器判断该 id
不存在,那么 StarRocks 可以直接返回空结果,而无需进一步扫描表或索引。
需要注意的是,布隆过滤器只能用于减少不必要的查询操作,而不能保证查询结果的准确性。因此,即使布隆过滤器判断某个 id
可能存在,我们仍然需要扫描表或索引来确认该 id
是否真的存在。
此外,布隆过滤器的误报率取决于其配置和使用的位数组大小。在实际应用中,我们需要根据数据的特性和查询需求来合理配置布隆过滤器,以达到最佳的查询性能和准确性。
案例2:假设我们有一个名为 users
的表,其中有一个 email
字段,我们想要在这个字段上创建一个布隆过滤器:
CREATE TABLE users ( id INT, email VARCHAR(255), name VARCHAR(255), age INT, INDEX idx_email_bloom (email) USING BLOOM_FILTER COMMENT 'Bloom filter on email' ) DISTRIBUTED BY HASH(id) BUCKETS 10;
INSERT INTO users (id, email, name, age) VALUES (1, 'user1@example.com', 'User One', 30); INSERT INTO users (id, email, name, age) VALUES (2, 'user2@example.com', 'User Two', 25); -- 插入更多数据...
SELECT * FROM users WHERE email LIKE 'user%';