Unity Catalog 托管表上的全文搜索索引

Important

此功能在 Beta 版中。 工作区管理员可以从 预览 页控制对此功能的访问。 请参阅 Manage Azure Databricks 预览版

全文搜索索引可加速对托管 Delta Lake 或 Iceberg 表中一个或多个文本列的查询。 索引支持子字符串匹配和单词匹配。 使用 searchisearch 函数查询表时,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 中的行跟踪
  • 索引列的类型为 STRINGVARIANTSTRUCTARRAYSTRING 列使用 UTF8_BINARY 排序规则。
  • STRUCT列在任意嵌套深度包含至少一个STRINGVARIANTARRAY叶字段;其他叶字段会被忽略。
  • 该表未使用限制条件列表中的任何功能,包括: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 INDEXREFRESH INDEX 在执行过程中失败,请运行 REFRESH INDEX 以从部分故障中恢复。

选项

OPTIONS 子句支持以下键:

Key Values 默认 Description
tokenizer ngramsplit 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);

使用 searchisearch 查询数据

Azure Databricks有两个 SQL 函数,用于测试一个或多个文本目标中是否存在搜索模式:

  • search:区分大小写。
  • isearch:不区分大小写。

根据是否区分大小写的要求,选择 searchisearch。 当索引列被全文搜索索引涵盖时,Azure Databricks 会使用该索引跳过确定不包含匹配行的文件。 搜索索引不会影响结果。

当搜索模式仅出现在表中的一小部分文件中时,索引对查询的加速效果最明显。

search( target [, target ... ] , 'pattern' [, mode => 'substring' | 'word' ] )
isearch( target [, target ... ] , 'pattern' [, mode => 'substring' | 'word' ] )

Arguments

searchisearch 接受以下参数:

  • target 必须为 STRINGVARIANTSTRUCTARRAY 类型,即索引所允许的相同类型。 重复数据删除目标。
  • pattern 必须是非 null 的字符串字面量。
  • mode指定pattern如何与每个target匹配:
    • substring(默认值):pattern 在每个 target 中被匹配为子字符串。
    • wordpattern 使用与 split 分词器相同的规则拆分为单词标记。 如果每个单词至少出现在一个目标中 pattern ,而不考虑顺序,则该函数将返回 true。 请参阅 为您的用例选择分词器

Returns

searchisearch 返回采用三值逻辑的 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将忽略搜索索引。