前缀索引和排序键
功能简介
建表时指定一个或多个列构成排序键 (Sort Key)。表中的数据行会根据排序键进行排序以后再落入磁盘存储。
并且数据写入的过程中会自动生成前缀索引。数据按照指定的排序键排序后,每写入 1024 行数据构成一个逻辑数据块(Data Block),在前缀索引表中存储一个索引项,内容为该逻辑数据块中第一行数据的排序列组成的前缀。
通过这样两层的排序结构,查询时就可以使用二分查找快速跳过不符合条件的数据。
前缀索引是一种稀疏索引,其大小至少会比数据量小 1024 倍,因此一般可以全量缓存在内存中,加速查询性能。
使用说明
自 3.0 版本起,主键表支持使用 ORDER BY
定义排序键,自 3.3 版本起,明细表、聚合表和更新表支持使用 ORDER BY
定义排序键。
- 明细表中数据按照排序键
ORDER BY
排序,排序键可 以为任意列的排列组合。信息如果同时指定
ORDER BY
和DUPLICATE KEY
,则DUPLICATE KEY
不生效。 - 聚合表中数据先按照聚合键
AGGREGATE KEY
进行聚合后,再按照排序键ORDER BY
排序。ORDER BY
和AGGREGATE KEY
中的列需要保持一致,但是列的顺序不需要保持一致。 - 更新表中数据先按照唯一键
UNIQUE KEY
进行 REPLACE 后,再按照排序键ORDER BY
排序。ORDER BY
和UNIQUE KEY
中的列需要保持一致,但是列的顺序不需要保持一致。 - 主键表中数据先按照主键
PRIMARY KEY
进行 REPLACE 后,再按照排序键ORDER BY
排序。
以明细表为例,使用 ORDER BY
定义排序键为 uid
和 name
。
CREATE TABLE user_access (
uid int,
name varchar(64),
age int,
phone varchar(16),
last_access datetime,
credits double
)
ORDER BY (uid, name);
建表后可以 通过 SHOW CREATE TABLE <table_name>;
在返回结果中的 ORDER BY
子句中查看指定的排序列和排序列的顺序。
由于前缀索引项的最大长度为 36 字节,超过部分会被截断,因此该表的前缀索引项为 uid (4 字节) + name (只取前 32 字节),前缀字段为 uid
和 name
。
注意事项
-
前缀字段的数量不超过 3 个,前缀索引项的最大长度为 36 字节。
-
前缀字段中 CHAR、VARCHAR、STRING 类型的列只能出现一次,并且处在末尾位置。
假设存在下表,其中前三列为排序列,前缀字段为
name
(20 字节)。即使索引项没有达到 36 个字节,因为前缀索引以 VARCHAR 类型的列开始,所以直接截断,不再往后继续。所以,这里前缀索引只含有字段name
。MySQL [example_db]> describe user_access2;
+-------------+-------------+------+-------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-------+---------+-------+
| name | varchar(20) | YES | true | NULL | |
| uid | int | YES | true | NULL | |
| last_access | datetime | YES | true | NULL | |
| age | int | YES | false | NULL | |
| phone | varchar(16) | YES | false | NULL | |
| credits | double | YES | false | NULL | |
+-------------+-------------+------+-------+---------+-------+
6 rows in set (0.00 sec) -
如果表中通过
ORDER BY
指定了排序键,就根据排序键构建前缀索引;如果没有通过ORDER BY
指定排序键,就根据 Key 列构建前缀索引。