CREATE INDEX
为表的单个列定义新的辅助索引 (2i) 或存储附加索引 (SAI)。
Apache Cassandra 支持在大多数列上创建辅助索引或存储附加索引,包括 PRIMARY KEY
的分区列和聚类列、集合和静态列。对于映射,您可以使用键、值或条目(键:值对)进行索引。
除以下列外,所有列数据类型都支持 SAI 索引
-
计数器
-
未冻结的用户定义类型 (UDT)
另请参阅:CREATE CUSTOM INDEX(用于存储附加索引 (SAI))、DROP INDEX
语法
BNF 定义
index_name::= re('[a-zA-Z_0-9]+')
CREATE INDEX [ IF NOT EXISTS ] <index_name> ON [<keyspace_name>.]<table_name> ( [ ( KEYS | FULL | ENTRIES ) ] <column_name>) // | [ (KEYS(<map_name>)) ] // | [ (VALUES(<map_name>)) ] // | [ (ENTRIES(<map_name>)) ] [USING 'sai'] [ WITH OPTIONS = { <option_map> } ];
语法约定 | 描述 |
---|---|
大写 |
文字关键字。 |
小写 |
非文字。 |
|
变量值。用用户定义的值替换。 |
|
可选。方括号 ( |
|
组。圆括号 ( |
|
或。竖线 ( |
|
可重复。省略号 ( |
|
单引号 ( |
|
映射集合。大括号 ( |
集合、列表、映射或元组。尖括号 ( |
|
|
结束 CQL 语句。分号 ( |
|
用两个连字符 ( |
|
仅搜索 CQL:单引号 ( |
|
仅搜索 CQL:标识实体和文字值以覆盖模式和 solrConfig 文件中的 XML 元素。 |
必需参数
参数 |
描述 |
table_name |
要索引的表的名称。 |
column_name |
要索引的列的名称。SAI 仅允许名称中包含字母数字字符和下划线。如果您尝试在包含其他字符的列名上定义索引,SAI 会返回 |
可选参数
参数 |
描述 |
index_name |
索引的名称。用引号括起来以使用特殊字符或保留大小写。如果未指定名称,Apache Cassandra 会将索引命名为 |
keyspace_name |
包含要索引的表的键空间的名称。如果未指定名称,则使用当前键空间。 |
map_name |
与 集合一起使用,在 |
option_map |
以 JSON 简单格式定义选项。 |
|
|
在匹配字符串值时忽略大小写。默认值: |
|
|
当设置为 当实现将字符串保留在规范化形式中时,等效字符串具有唯一的二进制表示形式。请参阅 Unicode 标准附件 #15,Unicode 规范化形式。 默认值: |
|
|
当设置为 |
|
|
向量搜索依赖于计算向量之间的相似度或距离来识别相关匹配项。相似度函数用于计算两个向量之间的相似度。有效选项为: |
使用说明
如果列已包含数据,则会在执行此语句期间对其进行索引。创建索引后,当列中的数据发生更改时,索引会自动更新。
使用 限制:不支持对计数器列进行索引。CREATE INDEX
命令进行索引可能会影响性能。在创建索引之前,请注意何时以及
SAI 索引
您可以在表中复合分区键的列之一上定义 SAI 索引,即包含多个列的分区键。如果您需要根据这些列之一进行查询,SAI 索引是一个有用的选项。实际上,您可以根据复合分区键中的每列定义 SAI 索引(如果需要)。
根据数据库表中任何列定义一个或多个 SAI 索引允许查询使用索引列来筛选结果。
SAI 查询运算符
SAI 支持以下查询运算符,用于具有 SAI 索引的表
-
数字:
=
、<
、>
、⇐
、>=
、AND
、OR
、IN
-
字符串:
=
、CONTAINS
、CONTAINS KEY
、AND
、OR
、IN
SAI 不支持以下查询运算符,用于具有 SAI 索引的表
-
字符串或数字:
LIKE
请参阅 SAI 部分。
示例
在聚类列上创建 SAI 索引
定义一个具有 复合分区键的表,然后在聚类列上创建索引。
CREATE TABLE IF NOT EXISTS cycling.rank_by_year_and_name (
race_year int,
race_name text,
cyclist_name text,
rank int,
PRIMARY KEY ((race_year, race_name), rank)
);
CREATE INDEX IF NOT EXISTS rank_idx
ON cycling.rank_by_year_and_name (rank);
SELECT * FROM rank_by_year_and_name WHERE rank = 1;
race_year | race_name | rank | cyclist_name
-----------+--------------------------------------------+------+-------------------
2014 | 4th Tour of Beijing | 1 | Phillippe GILBERT
2014 | Tour of Japan - Stage 4 - Minami > Shinshu | 1 | Daniel MARTIN
2015 | Giro d'Italia - Stage 11 - Forli > Imola | 1 | Ilnur ZAKARIN
2015 | Tour of Japan - Stage 4 - Minami > Shinshu | 1 | Benjamin PRADES
(4 rows)
在集合或列表集合上创建索引
与任何其他列一样,在集合或列表集合列上创建索引。在 CREATE INDEX
语句的末尾用圆括号括起集合列的名称。例如,将车队的集合添加到 cyclist_career_teams
表中,以索引车队集合中的数据。
CREATE TABLE IF NOT EXISTS cycling.cyclist_career_teams (
id UUID PRIMARY KEY,
lastname text,
teams set<text>
);
CREATE INDEX IF NOT EXISTS teams_idx
ON cycling.cyclist_career_teams (teams);
SELECT * FROM cyclist_career_teams WHERE teams CONTAINS 'Rabobank-Liv Woman Cycling Team';
id | lastname | teams
--------------------------------------+-----------------+------------------------------------------------------------------------------------------------------
5b6962dd-3f90-4c93-8f61-eabfa4a803e2 | VOS | {'Nederland bloeit', 'Rabobank Women Team', 'Rabobank-Liv Giant', 'Rabobank-Liv Woman Cycling Team'}
1c9ebc13-1eab-4ad5-be87-dce433216d40 | BRAND | {'AA Drink - Leontien.nl', 'Leontien.nl', 'Rabobank-Liv Giant', 'Rabobank-Liv Woman Cycling Team'}
e7cd5752-bc0d-4157-a80f-7523add8dbcd | VAN DER BREGGEN | {'Rabobank-Liv Woman Cycling Team', 'Sengers Ladies Cycling Team', 'Team Flexpoint'}
(3 rows)
在映射键上创建索引
您可以在map 集合键上创建索引。如果集合的 map 值存在索引,请在创建 map 集合键的索引之前删除该索引。假设 cyclist 表包含此 map 数据,其中nation 是 map 键,`Canada` 是 map 值
{'nation':'CANADA' }
要索引 map 键,请在 CREATE INDEX 语句中使用 KEYS
关键字和嵌套括号中的 map 名称。要对表运行 SELECT
查询,请在 WHERE
子句中使用CONTAINS KEY。此查询将返回在 2015 年有条目的自行车手团队。
CREATE TABLE IF NOT EXISTS cycling.cyclist_teams (
id uuid PRIMARY KEY,
firstname text,
lastname text,
teams map<int, text>
);
CREATE INDEX IF NOT EXISTS team_year_keys_idx
ON cycling.cyclist_teams ( KEYS (teams) );
SELECT *
FROM cycling.cyclist_teams
WHERE teams CONTAINS KEY 2015;
id | firstname | lastname | teams
--------------------------------------+-----------+------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
cb07baad-eac8-4f65-b28a-bddc06a0de23 | Elizabeth | ARMITSTEAD | {2011: 'Team Garmin - Cervelo', 2012: 'AA Drink - Leontien.nl', 2013: 'Boels:Dolmans Cycling Team', 2014: 'Boels:Dolmans Cycling Team', 2015: 'Boels:Dolmans Cycling Team'}
5b6962dd-3f90-4c93-8f61-eabfa4a803e2 | Marianne | VOS | {2015: 'Rabobank-Liv Woman Cycling Team'}
(2 rows)
在 map 条目上创建索引
您可以在 map 条目上创建索引。只能在没有现有索引的表的 map 列上创建 ENTRIES
索引。
要索引集合条目,请使用 ENTRIES
关键字和嵌套括号中的 map 名称。要查询表中的 map 条目,请使用带有 map 名称和值的 WHERE
子句。此查询将查找年龄相同的自行车手。
CREATE TABLE IF NOT EXISTS cycling.birthday_list (
cyclist_name text PRIMARY KEY,
blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_idx
ON cycling.birthday_list ( ENTRIES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist[ 'age' ] = '23';
cyclist_name | blist
------------------+----------------------------------------------------------
Claudio HEINEN | {'age': '23', 'bday': '27/07/1992', 'nation': 'GERMANY'}
Laurence BOURQUE | {'age': '23', 'bday': '27/07/1992', 'nation': 'CANADA'}
(2 rows)
使用相同的索引查找来自同一国家的自行车手
CREATE TABLE IF NOT EXISTS cycling.birthday_list (
cyclist_name text PRIMARY KEY,
blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_idx
ON cycling.birthday_list ( ENTRIES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist[ 'nation' ] = 'NETHERLANDS';
cyclist_name | blist
---------------+--------------------------------------------------------------
Luc HAGENAARS | {'age': '28', 'bday': '27/07/1987', 'nation': 'NETHERLANDS'}
Toine POELS | {'age': '52', 'bday': '27/07/1963', 'nation': 'NETHERLANDS'}
(2 rows)
在 map 值上创建索引
要创建 map 值的索引,请使用 VALUES
关键字和嵌套括号中的 map 名称。要查询表,请使用带有 map 名称及其包含值的 WHERE
子句。
CREATE TABLE IF NOT EXISTS cycling.birthday_list (
cyclist_name text PRIMARY KEY,
blist map<text, text>
);
CREATE INDEX IF NOT EXISTS blist_values_idx
ON cycling.birthday_list ( VALUES(blist) );
SELECT *
FROM cycling.birthday_list
WHERE blist CONTAINS 'NETHERLANDS';
cyclist_name | blist
---------------+--------------------------------------------------------------
Luc HAGENAARS | {'age': '28', 'bday': '27/07/1987', 'nation': 'NETHERLANDS'}
Toine POELS | {'age': '52', 'bday': '27/07/1963', 'nation': 'NETHERLANDS'}
(2 rows)
在冻结集合的完整内容上创建索引
您可以在完整的 FROZEN
集合上创建索引。可以在没有现有索引的表的 set、list 或 map 列上创建 FULL
索引。
在 FROZEN
list
的完整内容上创建索引。此示例中的表存储自行车手参加的职业胜利、大环赛和经典赛的次数。要索引集合条目,请使用 FULL
关键字和嵌套括号中的集合名称。例如,索引冻结列表 rnumbers
。要查询表,请使用带有集合名称和值的 WHERE
子句。
CREATE TABLE IF NOT EXISTS cycling.race_starts (
cyclist_name text PRIMARY KEY,
rnumbers FROZEN<LIST<int>>
);
CREATE INDEX IF NOT EXISTS rnumbers_idx
ON cycling.race_starts ( FULL(rnumbers) );
SELECT *
FROM cycling.race_starts
WHERE rnumbers = [39, 7, 14];
cyclist_name | rnumbers
----------------+-------------
John DEGENKOLB | [39, 7, 14]
(1 rows)