Lindorm提供了三種高效易用的索引:二級索引、搜索索引和列存索引,分別適用于非主鍵匹配場景、多維查詢場景和列存儲數據查詢場景。在使用CREATE INDEX語法創建索引時,您可以指定索引類型并添加索引屬性。
引擎與版本
CREATE INDEX語法僅適用于寬表引擎。無版本限制。
使用CREATE INDEX語法創建搜索索引、列存索引,要求Lindorm SQL為2.6.1以上版本。如何查看Lindorm SQL的版本,請參見SQL版本說明。
語法
create_index_statement ::= CREATE INDEX [IF NOT EXISTS] [ index_identifier ]
[ USING index_method_definition ]
ON table_identifier '(' index_key_expression ')'
[ INCLUDE include_expression]
[ PARTITION BY partition_definition ]
[ { ASYNC | SYNC} ]
[ WITH '(' index_options ')' ]
index_method_definition ::= { KV | SEARCH | COLUMNAR }
index_key_expression ::= '('
index_key_definition
|wildcard_string_literal
')'
index_key_definition ::= {
column_identifier [ DESC ]
| column_identifier'(' column_options ')'
| function_expression
}
[ (',' index_key_definition)* ]
column_options ::= '('
option_definition (',' option_definition )*
')'
function_expression ::= function_identifier
'('
column_identifer ( ',' column_identifer )*
')'
option_definition ::= option_identifer '=' string_literal
include_expression ::= '('
column_identifier( ',' column_identifier )*
')'
partition_definition ::= {
{RANGE TIME}
'('
column_identifer
')' [ PARTITIONS number_literal ]
|
HASH '('
column_identifer
( ',' column_identifer )*
')' [ PARTITIONS number_literal ]
|
ENUMERABLE
'('
column_identifer
( ',' column_identifer )*
index_options ::= '('
option_definition (',' option_definition )*
')'
差異說明
Lindorm寬表引擎支持通過CREATE INDEX語句創建三種索引:二級索引、搜索索引和列存索引。
不同的索引對語法要素的支持情況不同,具體如下:
語法要素 | 二級索引 | 搜索索引 | 列存索引 |
〇 | 〇 | 〇 | |
〇 | 〇 | ?? | |
〇 | ?? | ?? | |
?? | 〇 | 〇 | |
重要 僅寬表引擎2.6.3及以上版本支持 | 〇 | 〇 | 〇 |
〇 | 〇 | 〇 |
使用說明
每張寬表最多可創建3個二級索引、1個搜索索引和1個列存索引。
索引類型(index_method_definition)
您可以在創建索引時通過USING
關鍵字指定索引類型,Lindorm寬表引擎支持創建以下三種類型的索引:
參數 | 索引類型 | 說明 |
KV | 二級索引 | 當 重要 一個實例中僅允許同時存在8個二級索引的構建任務。如果某一時刻已有8個任務在執行,此時再創建二級索引,創建語句將執行失敗。 |
SEARCH | 搜索索引 | 基于搜索引擎的全文搜索索引。主要面向復雜的多維查詢場景,能夠覆蓋分詞、模糊查詢、聚合分析、排序翻頁等場景。詳細介紹,請參見搜索索引介紹。 搜索索引支持除DATE、TIME和DECIMAL外的所有基礎數據類型。數據類型的說明,請參見基礎數據類型。 重要
|
COLUMAR | 列存索引 | 創建列存索引。可以增強寬表中海量數據的分析計算能力,主要適用于車聯網與物聯網的設備信息統計、電商領域的數據分析、物流行業的訂單統計等場景。詳細介紹,請參見列存索引。 列存索引支持除DATE、TIME和TIMESTAMP外的所有基礎數據類型。數據類型的說明,請參見基礎數據類型。 重要
|
索引鍵表達式(index_key_expression)
您可以將一個列或多個列定義為索引鍵,由多個索引鍵構成的索引也稱為聯合索引。
索引鍵定義(index_key_definition)
如果索引類型為搜索索引,支持為索引鍵添加屬性。如果索引類型為二級索引,支持將索引鍵指定為一個函數表達式。
搜索索引鍵屬性(option_definition)
通過ALTER INDEX
語句增加索引列時,也可以指定索引鍵的屬性。例如c3(type=text,analyzer=ik)
表示為c3列創建索引,并指定c3列使用ik分詞器。
搜索索引中支持的索引鍵屬性如下所示:
索引鍵屬性 | 類型 | 描述 |
indexed | STRING | 是否為索引鍵中的指定列創建倒排索引。
|
rowStored | STRING | 是否存儲原始數據。
|
columnStored | STRING | 是否設置為列存儲,用來加速排序分析。
|
type | STRING | 分詞場景下,分詞字段需要設置type參數為text,其他情況默認與寬表數據類型保持一致。 重要 type參數必須與analyzer參數搭配使用。 |
analyzer | STRING | 分詞器列表。取值:
重要 analyzer參數必須與type參數搭配使用。 |
mapping | STRING | 自定義的索引鍵屬性,以字符串形式表示的JSON對象。兼容Elasticsearch索引鍵屬性語法。 重要
|
二級索引函數表達式(function_expression)
在創建二級索引時,可以將索引鍵指定為一個函數表達式。目前支持的函數表達式共五種:Z-ORDER函數、S2函數、CAST函數、MD5函數和SHA256函數。
重要僅寬表引擎2.6.7.5及以上版本,支持在創建索引時將索引鍵指定為MD5或SHA256函數表達式。如果您的寬表引擎無法通過控制臺進行升級,請聯系Lindorm技術支持(釘釘號:s0s3eg3)。
Z-ORDER函數:為一個或多個時空數據類型列創建時空二級索引。語法如下:
Z-ORDER '(' column_identifier ( ',' column_identifer )* ')'
column_identifer的數據類型必須為時空數據類型。關于時空索引的詳細介紹,請參見時空索引。?
CAST函數:對一個列類型進行數據類型轉換后的結果建立索引。語法如下:?
CAST(column_identifier AS type)
其中,type為數據類型,詳細介紹,請參見基礎數據類型。
S2函數:為一個時空數據類型列創建S2網格二級索引。語法如下:
S2 '(' column_identifier, level ')'
column_identifer的數據類型必須為POLYGON或MULTIPOLYGON,level的取值范圍為[1,30]。詳細介紹,請參見S2索引函數說明。
MD5函數:為一個VARCHAR類型列的MD5編碼值創建索引。語法如下:
MD5(column_identifier)
MD5函數的詳細介紹,請參見MD5函數。
SHA256函數:為一個VARCHAR類型列的SHA256編碼值創建索引。語法如下:
SHA256(column_identifier)
SHA256函數的詳細介紹,請參見SHA256函數。
通配符常量(wildcard_string_literal)
僅搜索索引和列存索引支持通配符常量(*)。
通配符常量(*)用于對所有列構建索引,例如CREATE INDEX IF NOT EXISTS idx5 USING SEARCH ON test(*);
。
在執行之后,后續增加的列不會自動添加到搜索索引和列存索引中,您需要通過
ALTER INDEX
語句自行添加。動態列不會被包含到索引中。詳細介紹,請參見動態列。
冗余列(include_expression)
僅二級索引和搜索索引支持通過INCLUDE
關鍵字冗余動態列以外的列。
冗余列是指在索引表中冗余一部分主表的列,也稱為冗余索引或覆蓋索引,目的是避免查詢命中索引后再回查主表,影響查詢性能。
二級索引可以通過WITH
關鍵字添加表屬性冗余動態列,詳細介紹,請參見二級索引。
索引分區(partition_definition)
僅搜索索引和列存索引支持索引分區。
索引分區是一種索引管理策略,服務端自動拆分并存儲數據,查詢數據時系統將自動裁剪分區。
搜索索引支持RANGE分區和HASH分區,詳細介紹,請參見分區索引。
列存索引僅支持ENUMERABLE分區,詳細介紹,請參見列存索引。
索引構建方式(ASYNC|SYNC)
在使用CREATE INDEX
語句創建索引時,可以通過ASYNC
或SYNC
關鍵字指定索引的構建方式。
ASYNC:異步構建索引。
CREATE INDEX
語句執行后立即開啟索引構建任務,無論索引是否構建成功,CREATE INDEX
語句立刻返回。SYNC:同步構建索引。
CREATE INDEX
語句執行后立即開啟索引構建任務,CREATE INDEX
語句在索引構建完畢后才返回。
三種索引對構建方式的支持情況如下:
索引構建方式 | 二級索引 | 搜索索引 | 列存索引 |
ASYNC 重要 自寬表引擎2.6.1版本開始,執行 | 〇 | 〇 | 〇 |
SYNC 重要 僅寬表引擎2.6.3及以上版本支持同步構建索引。 | 〇 | 〇 | ?? |
索引屬性(index_options)
通過CREATE INDEX
語句創建索引時,可以通過WITH
關鍵字指定索引屬性。支持的索引屬性如下所示。
二級索引
屬性 | 類型 | 說明 |
COMPRESSION | STRING | 索引表的壓縮算法,支持的壓縮算法包括:
|
INDEX_COVERED_TYPE | STRING | 索引的冗余方式,取值如下:
您也可以通過 |
STARTKEY | STRING | 索引表的起始Key。 重要 不支持為時間戳列或類型為空間數據類型的列設置起始Key。 |
ENDKEY | STRING | 索引表的終止Key。 重要 不支持為時間戳列或類型為空間數據類型的列設置終止Key。 |
NUMREGIONS | INTEGER | 索引表的預分區數。 重要 不支持為時間戳列或類型為空間數據類型的列設置預分區數。 |
搜索索引
屬性 | 類型 | 說明 |
indexState | STRING | 搜索索引狀態,取值如下:
|
numShards | INTEGER | 指定分片數,默認是搜索節點個數的兩倍。 |
RANGE_TIME_PARTITION_START | INTEGER | 表示創建索引操作前多少天開始創建分區。適用于有歷史數據的場景,當歷史數據的時間戳早于開始分區的時間時,會導致報錯。 說明 創建分區索引時,必須指定此參數。 |
RANGE_TIME_PARTITION_INTERVAL | INTEGER | 表示間隔多少天創建新分區,例如 說明 創建分區索引時,必須指定此參數。 |
RANGE_TIME_PARTITION_TTL | INTEGER | 表示保留多少天的分區數據,例如 說明 創建分區索引時,必須指定此參數。 |
RANGE_TIME_PARTITION_MAX_OVERLAP | INTEGER | 如果寫入的數據時間點是將來的時間,這個參數表示最多允許與當前時刻的時間間隔,單位為天。不指定時默認允許寫入未來1天的數據。 |
RANGE_TIME_PARTITION_FIELD_TIMEUNIT | LONG | 表示業務指定的時間分區字段單位,默認單位為毫秒(ms)。
|
RANGE_TIME_PARTITION_CHS | INTEGER | 冷熱分界線。表示將多久之前的數據轉移到冷存儲,默認單位為秒(s)。例如 說明 不設置該參數表示不開啟冷熱分離,數據默認只存儲在熱存儲中。 |
INDEX_SETTINGS | STRING | 自定義的索引屬性,以字符串形式表示的JSON對象。兼容Elasticsearch索引設置語法。 重要 INDEX_SETTINGS參數僅適用于搜索引擎Elasticsearch兼容版本。 |
列存索引
屬性 | 類型 | 說明 |
lindorm_columnar.user.index.database | STRING | 自定義列存表所屬Database。 |
lindorm_columnar.user.index.table | STRING | 自定義列存表的表名。 |
lindorm_columnar.user.syncer.skip.fullsync | BOOLEAN | 指示構建索引時是否跳過寬表中的存量數據,只為增量數據構建列存索引。 |
lindorm_columnar.user.syncer.lci.jsonMapping.json_col | STRING | 指定表中需要映射的JSON列。 |
由于列存索引的屬性名均通過分隔符(.)連接,因此為避免語義解釋上的偏差,在使用WITH
關鍵字添加表屬性時,必須在表屬性的前后添加反引號(`),將其作為完整的標識符使用。例如,WITH(`lindorm_columnar.user.syncer.skip.fullsync1` = 'true')
。
示例
假設主表test的建表語句如下:
CREATE TABLE test (
p1 VARCHAR NOT NULL,
p2 INTEGER NOT NULL,
c1 BIGINT,
c2 DOUBLE,
c3 VARCHAR,
c4 TIMESTAMP,
c5 GEOMETRY(POINT),
PRIMARY KEY(p1, p2)
) WITH (CONSISTENCY = 'strong', MUTABILITY='MUTABLE_LATEST');
二級索引
異步構建索引
不設置構建方法時,默認異步構建索引。
CREATE INDEX idx1 ON test(c1 desc) include(c3,c4) WITH (COMPRESSION='ZSTD');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
創建聯合索引
為c1,c2,c3列同步創建聯合索引。
CREATE INDEX idx1 ON test(c1, c2, c3) include(c4) SYNC WITH ( COMPRESSION ='ZSTD');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
冗余所有列
CREATE INDEX idx1 ON test(c4 desc) WITH (INDEX_COVERED_TYPE ='COVERED_ALL_COLUMNS_IN_SCHEMA');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
冗余所有動態列
CREATE INDEX idx1 ON test(c4 desc) WITH (INDEX_COVERED_TYPE='COVERED_DYNAMIC_COLUMNS');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
設置索引表的預分區數
設置索引表的預分區數為32。
CREATE INDEX idx1 ON test(c4 desc) include(c5,c6) WITH (NUMREGIONS ='32');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
指定索引表的起止Key
創建二級索引時指定索引表的起止Key和預分區數,將索引表在11111111
和9999999
之間分成32個預分區。
CREATE INDEX idx1 ON test(c3 desc) include(c5,c6) WITH (NUMREGIONS ='32', STARTKEY ='11111111', ENDKEY = '9999999');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
創建Z-ORDER二級索引
為面數據類型列c5創建Z-ORDER二級索引。?
CREATE INDEX idx1 ON test(Z-ORDER(c5));
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
創建網格二級索引
為面類型列c5創建網格二級索引。目前僅支持異步創建模式。
CREATE INDEX idx1 ON test(S2(c5, 10));
構建網格二級索引。
BUILD INDEX s2_idx ON test;
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
轉換指定列的數據類型
將c3列的數據類型轉換為INTEGER類型后創建二級索引。?
CREATE INDEX idx1 ON test(CAST(c3 AS INTEGER));
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
搜索索引
異步構建索引
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test(p1, p2, c1, c2, c3);
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
為所有列創建索引
為所有列創建搜索索引,不指定具體列屬性時,均為默認值。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test('*');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
添加索引鍵屬性
添加非自定義索引鍵屬性
創建所有列的搜索索引,如果索引列有c3, 索引列的屬性都為type=text,analyzer=ik,indexed=true。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test('*',c3(type=text,analyzer=ik,indexed=true));
結果驗證
您可以執行
SHOW INDEX FROM test;
查看索引是否已創建成功。添加自定義索引鍵屬性
假設表結構如下:
CREATE TABLE test ( p1 VARCHAR NOT NULL, p2 INTEGER NOT NULL, c1 BIGINT, c2 DOUBLE, c3 VARCHAR, c4 TIMESTAMP, PRIMARY KEY(p1, p2) ) WITH (CONSISTENCY = 'strong', MUTABILITY='MUTABLE_LATEST');
創建所有列的搜索索引,其中索引列c3指定類型為text,分詞器為ik_max_word。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test('*',c3(mapping='{ "type": "text", "analyzer": "ik_max_word" }'));
重要mapping參數僅適用于搜索引擎Elasticsearch兼容版本。
若使用了mapping參數,該索引鍵的其它所有參數將無效。
結果驗證
您可以執行
SHOW INDEX FROM test;
查看索引是否已創建成功。
設置索引狀態
指定列,并指定部分列屬性,同時指定搜索索引狀態為ACTIVE。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test(c1, c3(type=text,analyzer=ik)) WITH (indexState=ACTIVE,numShards=4);
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
設置自定義索引屬性
創建搜索索引,指定搜索索引狀態為ACTIVE,并通過自定義設置指定索引的分片數量為4,壓縮方式為ZSTD,刷新時間間隔為10秒。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test(c1, c3(type=text,analyzer=ik)) WITH (indexState=ACTIVE,INDEX_SETTINGS='{
"index": {
"codec": "zstd",
"refresh_interval": "10s",
"number_of_shards": 4
}
}');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
設置時間分區
按時間列c4分區,從30天前開始,每7天自動分區,默認保留90天的分區數據。
CREATE INDEX IF NOT EXISTS idx2 USING SEARCH ON test (c1, c2, c3, c4)
PARTITION BY RANGE TIME(c4) PARTITIONS 16
WITH (indexState=ACTIVE, RANGE_TIME_PARTITION_START='30', RANGE_TIME_PARTITION_INTERVAL='7', RANGE_TIME_PARTITION_TTL='90', RANGE_TIME_PARTITION_MAX_OVERLAP='90');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
列存索引
創建索引
CREATE INDEX IF NOT EXISTS idx3 USING COLUMNAR
ON test(p1, p2, c1, c2, c3)
PARTITION BY ENUMERABLE (p1, p2, bucket(128, p1, p2));
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
自定義列存表名
創建列存索引,將索引表命名為my_index_tbl
。
CREATE INDEX IF NOT EXISTS idx3 USING COLUMNAR ON test(*)
PARTITION BY ENUMERABLE (p1, p2, bucket(128, p1, p2))
WITH (`lindorm_columnar.user.index.database` = 'my_index_db',
`lindorm_columnar.user.index.table` = 'my_index_tbl');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
創建增量列存索引
創建一個僅為增量數據構建列存索引的索引。
CREATE INDEX IF NOT EXISTS idx3 USING COLUMNAR ON test(*)
PARTITION BY ENUMERABLE (p1, p2, bucket(128, p1, p2))
WITH (`lindorm_columnar.user.syncer.skip.fullsync` = 'true');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。
為JSON列展開后的字段創建索引
針對JSON列展開后的字段創建列存索引。假設包含JSON列的表建表語句如下:
CREATE TABLE IF NOT EXISTS my_json_tbl(id BIGINT, col1 INTEGER, col2 DOUBLE, json_col JSON, PRIMARY KEY(id));
寫入JSON數據的結構如下:
{
"a": {
"b": {
"c": "hello,world",
"d": 123
},
"e": false
},
"f": 3.14
}
創建列存索引時,基于WITH
關鍵字,指定展開JSON字段的映射規則。
CREATE INDEX IF NOT EXISTS columnar_idx USING COLUMNAR ON my_json_tbl(*)
PARTITION BY ENUMERABLE (id%16, bucket(16,id))
WITH (
`lindorm_columnar.user.syncer.lci.jsonMapping.json_col` = 'a.b.c VARCHAR, a.e BOOLEAN ,f DOUBLE');
結果驗證
您可以執行SHOW INDEX FROM test;
查看索引是否已創建成功。