Important
此功能在 Beta 版中。 工作区管理员可以从 预览 页控制对此功能的访问。 请参阅 Manage Azure Databricks 预览版。
全文搜索索引可加速对托管 Delta Lake 或 Iceberg 表中一个或多个文本列的查询。 索引支持子字符串匹配和单词匹配。 使用 search 或 isearch 函数查询表时,Azure Databricks 会利用索引跳过可确定不包含匹配行的文件。 这大大减少了扫描的数据量,尤其是在选择性查询时。
Important
在 Beta 版本中创建的索引不能保证与更高版本兼容。 当该功能达到公共预览版时,必须删除现有索引并创建新的索引。
要求
全文搜索索引具有计算、基表和架构权限以及基表配置的要求。
计算
全文搜索索引仅在 Azure Databricks Runtime 18.2 及更高版本中可用,必须在工作区设置中启用此 Beta 功能。 请参阅 Manage Azure Databricks 预览版。
Permissions
创建搜索索引:
- 必须对搜索索引中引用的表具有
MODIFY权限。 - 您必须在父架构上具有
CREATE TABLE权限。 具有 MANAGE 权限的架构所有者或用户可以授予你CREATE TABLE对架构的权限。
表配置
在创建全文搜索索引之前,基表必须满足以下所有要求:
- 必须在与基表相同的目录和架构中创建索引。
- 该表是托管的 Delta Lake 表或 Iceberg 表。
- 行跟踪已启用 (
delta.enableRowTracking = true)。 请参阅 Databricks 中的行跟踪。 - 索引列的类型为
STRING、VARIANT、STRUCT或ARRAY。STRING列使用UTF8_BINARY排序规则。 -
STRUCT列在任意嵌套深度包含至少一个STRING、VARIANT或ARRAY叶字段;其他叶字段会被忽略。 - 该表未使用限制条件列表中的任何功能,包括:Delta Sharing、浅克隆、基于属性的访问控制、行级安全策略和列掩码。 请参阅限制。
有关适用于 Delta Lake 和 Iceberg 表的表协议要求的信息,请参阅 Delta Lake 功能兼容性和协议。
创建全文搜索索引
可以在单个表上创建最多四个索引,每个索引位于不同的列上。 四索引限制由全文搜索索引和辅助索引共享。 请参阅 Unity 目录托管表上的辅助索引。
使用 CREATE SEARCH INDEX 为一个或多个文本列创建索引。 以下示例为现有日志表的两个文本列编制索引:
CREATE SEARCH INDEX log_idx
ON logs (message, error_detail);
完整语法为:
CREATE SEARCH INDEX [IF NOT EXISTS] index_name
ON table_name ( column_name [, column_name ...] )
[OPTIONS ( option_key = option_value [, ... ] )]
index_name 在架构中必须是唯一的,并且不能与现有表名匹配。
若要控制文本的标记方式,请参阅 “选项”。
Warning
如果 CREATE SEARCH INDEX 和 REFRESH INDEX 在执行过程中失败,请运行 REFRESH INDEX 以从部分故障中恢复。
选项
该 OPTIONS 子句支持以下键:
| Key | Values | 默认 | Description |
|---|---|---|---|
tokenizer |
ngram、split |
ngram |
如何对文本进行标记以便编制索引。 请参阅 为您的用例选择分词器。 |
ngram_size |
[3, 10] 中的整数 |
5 |
生成的 n 元语法的长度。 仅当 tokenizer = 'ngram' 时有效。 |
min_token_length |
整数 >= 1 |
3 |
要保留的令牌的最小长度。 在编制索引时,长度短于此值的词元会被丢弃。 仅当 tokenizer = 'split' 时有效。 |
有关无效选项错误的详细信息,请参阅 SEARCH_INDEX_INVALID_PARAMETERS错误条件。
为您的使用场景选择分词器
搜索索引有 2 个可用的 tokenizer 选项,具体取决于你的用例:
| 分词器 | 用例 | Description |
|---|---|---|
ngram |
子字符串匹配。 | 将文本拆分为长度为 ngram_size 的重叠 n-gram。 |
split |
整词包含检查。 | 将文本拆分为单词标记。 令牌是由 Unicode 字母(\p{L})和组合标记(\p{M})构成的连续序列;任何其他字符都是分隔符。 |
若要创建 n 元语法索引,其 n 元语法大小为 4:
CREATE SEARCH INDEX log_ngram_idx
ON logs (message)
OPTIONS (tokenizer = 'ngram', ngram_size = 4);
若要创建 split 最小令牌长度为 2 的索引,请执行以下操作:
CREATE SEARCH INDEX log_word_idx
ON logs (message)
OPTIONS (tokenizer = 'split', min_token_length = 2);
使用 search 和 isearch 查询数据
Azure Databricks有两个 SQL 函数,用于测试一个或多个文本目标中是否存在搜索模式:
-
search:区分大小写。 -
isearch:不区分大小写。
根据是否区分大小写的要求,选择 search 或 isearch。 当索引列被全文搜索索引涵盖时,Azure Databricks 会使用该索引跳过确定不包含匹配行的文件。 搜索索引不会影响结果。
当搜索模式仅出现在表中的一小部分文件中时,索引对查询的加速效果最明显。
search( target [, target ... ] , 'pattern' [, mode => 'substring' | 'word' ] )
isearch( target [, target ... ] , 'pattern' [, mode => 'substring' | 'word' ] )
Arguments
search 并 isearch 接受以下参数:
-
target必须为STRING、VARIANT、STRUCT或ARRAY类型,即索引所允许的相同类型。 重复数据删除目标。 -
pattern必须是非 null 的字符串字面量。 -
mode指定pattern如何与每个target匹配:-
substring(默认值):pattern在每个target中被匹配为子字符串。 -
word:pattern使用与split分词器相同的规则拆分为单词标记。 如果每个单词至少出现在一个目标中pattern,而不考虑顺序,则该函数将返回 true。 请参阅 为您的用例选择分词器。
-
Returns
search 和 isearch 返回采用三值逻辑的 BOOLEAN 值:
-
true如果至少有一个非空目标匹配。 -
null如果没有非空目标匹配,但至少有一个目标是null。 -
false如果所有目标均为非空且都不匹配。
例子
以下示例显示了常见 search 查询和 isearch 查询:
-- Case-insensitive substring search across one column.
SELECT * FROM logs
WHERE isearch(message, 'connection refused');
-- Case-sensitive substring search across multiple columns.
SELECT * FROM logs
WHERE search(message, error_detail, '550e8400-e29b-41d4-a716-446655440000');
-- Word search: matches rows containing all three words, in any order.
SELECT * FROM audit_logs
WHERE search(message, 'user admin login', mode => 'word');
管理索引
Important
全文搜索索引在基表更改时不会自动更新。 请参阅 “刷新索引”。
无论索引新鲜度如何,Azure Databricks都保持查询正确性。 当表包含非索引数据时,查询使用现有索引来加速对索引记录的访问,并使用对非索引记录的表扫描。
使用以下操作管理全文搜索索引:
描述或查看索引
若要查看有关索引的信息:
DESCRIBE INDEX log_idx;
刷新索引
全文搜索索引在基表更改时不会自动更新。
若要更新索引,请为新行添加条目:
REFRESH INDEX log_idx;
REFRESH INDEX 是一种增量式、仅追加的操作。 它为新数据编制索引,但不会删除已删除行的条目。
若要更新索引,请同时为新行添加条目和删除已删除行的条目,请使用 REFRESH INDEX ... FULL:
REFRESH INDEX log_idx FULL;
完全刷新需要比增量刷新更多的计算资源。 随着时间的推移,增量刷新会累积过时的条目,从而增加索引的大小,并对性能产生负面影响。
删除索引
若要删除索引,请运行以下命令:
DROP INDEX log_idx;
若要避免缺少索引的错误,请使用:
DROP INDEX IF EXISTS log_idx;
注释
如果删除基表,该命令也会删除全文搜索索引。
局限性
全文搜索索引具有以下限制:
- 不支持重命名基表上的索引列或更改其数据类型。
- 不支持启用了 Delta Sharing 的表。 如果在创建索引后将基表用作 Delta Sharing 源或目标,Azure Databricks 会忽略该搜索索引。
- 不支持浅克隆表。 如果在创建索引后将基表添加为浅表克隆源,Azure Databricks将忽略搜索索引。