【金仓数据库征文】LIKE查询优化:前缀、后缀与全文检索边界

文章目录

    • 每日一句正能量
    • [1. 背景与问题](#1. 背景与问题)
    • [2. 环境与数据](#2. 环境与数据)
      • [2.1 实验环境](#2.1 实验环境)
      • [2.2 样例表](#2.2 样例表)
      • [2.3 数据分布检查](#2.3 数据分布检查)
    • [3. 复现过程](#3. 复现过程)
      • [3.1 精确匹配:普通 B-tree 索引最擅长的场景](#3.1 精确匹配:普通 B-tree 索引最擅长的场景)
      • [3.2 前缀匹配:不是所有环境都会自动使用普通索引](#3.2 前缀匹配:不是所有环境都会自动使用普通索引)
      • [3.3 后缀匹配:普通索引顺序与查询方向相反](#3.3 后缀匹配:普通索引顺序与查询方向相反)
      • [3.4 任意位置包含:`LIKE '%科技%'` 的根本边界](#3.4 任意位置包含:LIKE '%科技%' 的根本边界)
      • [3.5 全文检索不是 `%keyword%` 的等价替换](#3.5 全文检索不是 %keyword% 的等价替换)
    • [4. 方案实施](#4. 方案实施)
      • [4.1 先拆分搜索语义,而不是让一条 SQL 承担所有需求](#4.1 先拆分搜索语义,而不是让一条 SQL 承担所有需求)
      • [4.2 前缀查询方案](#4.2 前缀查询方案)
      • [4.3 后缀查询方案](#4.3 后缀查询方案)
      • [4.4 任意位置包含方案](#4.4 任意位置包含方案)
      • [4.5 全文检索方案](#4.5 全文检索方案)
      • [4.6 数据校验](#4.6 数据校验)
      • [4.7 灰度发布与回退](#4.7 灰度发布与回退)
    • [5. 结果对比](#5. 结果对比)
      • [5.1 示例测试结果](#5.1 示例测试结果)
      • [5.2 不能只比较执行时间](#5.2 不能只比较执行时间)
      • [5.3 写入成本对比](#5.3 写入成本对比)
    • [6. 风险与复盘](#6. 风险与复盘)
      • [6.1 前缀匹配的风险](#6.1 前缀匹配的风险)
      • [6.2 后缀匹配的风险](#6.2 后缀匹配的风险)
      • [6.3 全文检索的风险](#6.3 全文检索的风险)
      • [6.4 常见错误做法](#6.4 常见错误做法)
      • [6.5 最终决策](#6.5 最终决策)

每日一句正能量

我们不曾走过他人的路,便难以体会其经历的全部重量。

每个人的人生轨迹、苦难和挣扎都是独特的,没有亲身经历过,就无法真正理解那种沉重。因此应保持谦卑和审慎。


1. 背景与问题

客户中心上线统一检索后,运营人员习惯在一个输入框中搜索客户名称。接口最初只有一条 SQL:

sql 复制代码
SELECT customer_id, customer_name, customer_level, city_name
FROM crm_customer
WHERE customer_name LIKE '%' || :keyword || '%'
ORDER BY updated_at DESC
LIMIT 20;

业务上看,这条 SQL 很自然:输入"科技"可以查到"华北科技有限公司",输入"银行"可以查到"城市商业银行股份有限公司"。但随着客户表从几十万行增长到数百万行,接口 P95 从 120 ms 上升到 2 s 以上。数据库监控显示,该 SQL 调用频率不算最高,却长期位于共享块访问量和 CPU 消耗榜单前列。

问题并不只是"缺少索引"。客户名称搜索至少包含四种不同语义:

  1. 精确匹配:完整输入客户名称。
  2. 前缀匹配:输入"华北科",希望匹配"华北科技有限公司"。
  3. 后缀匹配:输入"有限公司",希望匹配所有以该词结尾的名称。
  4. 任意位置包含:输入"科技",名称中任何位置出现均应命中。
  5. 自然语言检索:将名称、简称、曾用名、经营标签作为一个文档检索,并按相关度排序。

这几类需求虽然都可以用 LIKE 表达,却不应使用同一种索引和同一条 SQL。若把所有搜索都压到 LIKE '%关键字%',数据库只能面对一个高频、低选择率、难以利用普通 B-tree 索引的通用查询。

本次优化的目标不是简单把一个顺序扫描改成索引扫描,而是回答三个问题:

  • 前缀、后缀和任意位置包含查询,分别应该采用什么数据结构?
  • 全文检索能否替代所有模糊搜索?
  • 优化后是否同时改善延迟、I/O 与并发,而不是只让单次实验更快?

2. 环境与数据

2.1 实验环境

项目 示例配置
数据库 KingbaseES V8/V9 兼容环境
表规模 500 万行客户数据
平均名称长度 18 个中文字符
名称唯一率 约 92%
热点词 "科技""集团""有限公司""银行"
测试方式 冷缓存、热缓存各 10 轮
观察指标 执行时间、P95、共享块、实际扫描行数、索引体积、写入 TPS

不同版本、兼容模式、排序规则和已安装扩展会影响语法及执行计划。本文给出的 SQL 需要先在测试环境确认。

2.2 样例表

sql 复制代码
CREATE TABLE crm_customer (
    customer_id      BIGINT PRIMARY KEY,
    tenant_id        BIGINT NOT NULL,
    customer_name    VARCHAR(200) NOT NULL,
    short_name       VARCHAR(100),
    former_name      VARCHAR(200),
    customer_level   VARCHAR(20),
    city_name        VARCHAR(60),
    search_document  TSVECTOR,
    updated_at       TIMESTAMP NOT NULL
);

基础索引:

sql 复制代码
CREATE INDEX idx_customer_name
ON crm_customer(customer_name);

CREATE INDEX idx_customer_tenant_update
ON crm_customer(tenant_id, updated_at DESC);

2.3 数据分布检查

优化前先确认关键词命中比例。低选择率词即使能使用索引,也可能需要访问大量索引项和表页。

sql 复制代码
SELECT
    COUNT(*) AS total_rows,
    COUNT(*) FILTER (WHERE customer_name LIKE '华北科%') AS prefix_rows,
    COUNT(*) FILTER (WHERE customer_name LIKE '%有限公司') AS suffix_rows,
    COUNT(*) FILTER (WHERE customer_name LIKE '%科技%') AS contains_rows
FROM crm_customer;

再检查名称长度和高频词:

sql 复制代码
SELECT
    MIN(char_length(customer_name)) AS min_len,
    MAX(char_length(customer_name)) AS max_len,
    AVG(char_length(customer_name)) AS avg_len
FROM crm_customer;

SELECT customer_name, COUNT(*)
FROM crm_customer
GROUP BY customer_name
ORDER BY COUNT(*) DESC
LIMIT 20;

实验中,"华北科%"命中约 0.018%,"%有限公司"命中约 31%,"%科技%"命中约 4.6%。这三个比例决定了后续计划差异。


3. 复现过程

3.1 精确匹配:普通 B-tree 索引最擅长的场景

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS)
SELECT customer_id, customer_name
FROM crm_customer
WHERE customer_name = '华北科技有限公司';

典型计划:

text 复制代码
Index Scan using idx_customer_name on crm_customer
  Index Cond: (customer_name = '华北科技有限公司')
  Buffers: shared hit=8
  Execution Time: 0.18 ms

精确匹配条件可以直接定位 B-tree 中的键值范围,访问块少,计划稳定。

3.2 前缀匹配:不是所有环境都会自动使用普通索引

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS)
SELECT customer_id, customer_name
FROM crm_customer
WHERE customer_name LIKE '华北科%';

在合适排序规则和操作符类条件下,优化器可以把前缀匹配转换成一个有上下界的索引范围。但如果数据库使用非 C/POSIX 排序规则,普通文本索引未必能直接支持 LIKE 前缀范围,可能仍出现顺序扫描。

复现中基线计划为:

text 复制代码
Seq Scan on crm_customer
  Filter: (customer_name ~~ '华北科%')
  Rows Removed by Filter: 4999102
  Buffers: shared hit=18421 read=23170
  Execution Time: 731.44 ms

这类问题容易被误判为"LIKE 前缀也无法用索引"。真正需要检查的是排序规则、操作符类、表达式和参数绑定。

可选改造:

sql 复制代码
CREATE INDEX idx_customer_name_pattern
ON crm_customer (customer_name text_pattern_ops);

若当前 KingbaseES 版本支持对应操作符类,前缀计划可变为:

text 复制代码
Index Scan using idx_customer_name_pattern on crm_customer
  Index Cond: ((customer_name ~>=~ '华北科')
           AND (customer_name ~<~  '华北秕'))
  Filter: (customer_name ~~ '华北科%')
  Buffers: shared hit=126
  Execution Time: 4.62 ms

边界字符由数据库内部规则生成,不建议在业务 SQL 中自行拼接"下一个字符串"。

3.3 后缀匹配:普通索引顺序与查询方向相反

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS)
SELECT customer_id, customer_name
FROM crm_customer
WHERE customer_name LIKE '%有限公司';

B-tree 按字符串左侧开始排序,而后缀条件不知道字符串的起点,因此普通名称索引无法直接缩小扫描区间。计划通常为顺序扫描:

text 复制代码
Seq Scan on crm_customer
  Filter: (customer_name ~~ '%有限公司')
  Actual Rows: 1550021
  Buffers: shared hit=19106 read=22511
  Execution Time: 1684.52 ms

即使创建了表达式反转索引,如果命中 31% 的数据,优化器仍可能判断顺序扫描更便宜。索引可用不等于索引一定更快。

后缀固定且高频时,可以建立反转列:

sql 复制代码
ALTER TABLE crm_customer
ADD COLUMN customer_name_rev VARCHAR(200);

UPDATE crm_customer
SET customer_name_rev = reverse(customer_name);

CREATE INDEX idx_customer_name_rev
ON crm_customer(customer_name_rev text_pattern_ops);

查询改为:

sql 复制代码
SELECT customer_id, customer_name
FROM crm_customer
WHERE customer_name_rev LIKE reverse(:suffix) || '%';

但此方案需要应用或触发器维护反转列,并且更适合命中比例较低、后缀检索确实是核心需求的场景。对"有限公司"这类超高频后缀,返回数据量本身已经很大,分页、附加过滤和业务口径收敛比单纯建索引更重要。

3.4 任意位置包含:LIKE '%科技%' 的根本边界

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS)
SELECT customer_id, customer_name
FROM crm_customer
WHERE customer_name LIKE '%科技%';

普通 B-tree 无法定位中间子串。基线计划:

text 复制代码
Seq Scan on crm_customer
  Filter: (customer_name ~~ '%科技%')
  Actual Rows: 230418
  Rows Removed by Filter: 4769582
  Buffers: shared hit=18854 read=22772
  Execution Time: 1412.77 ms

此时有三条路线:

  1. 对固定、有限关键词建设业务标签列。
  2. 使用支持子串相似度检索的扩展索引,例如 trigram/GIN(需确认版本与插件)。
  3. 将需求改造成全文检索,但必须接受"词项匹配"与"字面子串匹配"不是同一语义。

3.5 全文检索不是 %keyword% 的等价替换

全文检索通常将文档解析为词位,再通过 tsvectortsquery 匹配。它擅长关键词组合、逻辑查询、相关度排序和多字段检索,但不天然保证任意连续字符子串命中。

构建搜索文档:

sql 复制代码
UPDATE crm_customer
SET search_document =
    to_tsvector(
        'simple',
        coalesce(customer_name, '') || ' ' ||
        coalesce(short_name, '') || ' ' ||
        coalesce(former_name, '')
    );

CREATE INDEX idx_customer_search_document
ON crm_customer
USING GIN(search_document);

查询:

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS)
SELECT customer_id,
       customer_name,
       ts_rank(search_document, plainto_tsquery('simple', :keyword)) AS rank_score
FROM crm_customer
WHERE search_document @@ plainto_tsquery('simple', :keyword)
ORDER BY rank_score DESC
LIMIT 20;

典型计划可能包含:

text 复制代码
Bitmap Heap Scan on crm_customer
  Recheck Cond: (search_document @@ plainto_tsquery('simple', '科技'))
  -> Bitmap Index Scan on idx_customer_search_document
       Index Cond: (search_document @@ plainto_tsquery('simple', '科技'))

对于中文名称,使用哪种分词配置、词典或扩展必须根据实际版本验证。若使用 simple 配置,中文长字符串可能被当作一个整体词项,无法达到预期分词效果。正式方案应先用真实名称样本验证分词结果:

sql 复制代码
SELECT to_tsvector('simple', '华北科技有限公司');

如果结果不能满足"科技"检索,就不能仅凭创建 GIN 索引宣称全文检索成功。


4. 方案实施

4.1 先拆分搜索语义,而不是让一条 SQL 承担所有需求

接口改造成明确的搜索模式:

text 复制代码
EXACT      精确名称
PREFIX     名称前缀
SUFFIX     名称后缀
CONTAINS   任意位置包含
FULLTEXT   多字段关键词与相关度搜索

默认搜索建议采用"前缀优先 + 全文补充",而不是默认包含搜索。用户输入短于 2 个字符时,拒绝全库模糊查询,提示增加关键词或选择租户、城市等筛选条件。

4.2 前缀查询方案

SQL:

sql 复制代码
SELECT customer_id, customer_name, customer_level, city_name
FROM crm_customer
WHERE tenant_id = :tenant_id
  AND customer_name LIKE :prefix || '%'
ORDER BY customer_name
LIMIT :page_size;

候选索引:

sql 复制代码
CREATE INDEX idx_customer_tenant_name_pattern
ON crm_customer(tenant_id, customer_name text_pattern_ops);

验证重点:

  • Index Cond 是否同时包含租户和名称范围。
  • 是否仍存在大规模 Rows Removed by Filter
  • 排序是否可以利用索引顺序。
  • :prefix 是否以字符串类型绑定。
  • 排序规则是否允许该操作符类工作。

4.3 后缀查询方案

仅当后缀检索是高价值且命中率可控时采用反转列。推荐生成列或应用层统一维护,具体语法需按版本验证。

sql 复制代码
CREATE INDEX idx_customer_tenant_name_rev
ON crm_customer(tenant_id, customer_name_rev text_pattern_ops);

查询:

sql 复制代码
SELECT customer_id, customer_name
FROM crm_customer
WHERE tenant_id = :tenant_id
  AND customer_name_rev LIKE reverse(:suffix) || '%'
ORDER BY updated_at DESC
LIMIT 20;

必须同时处理:

  • 新增、修改、批量导入时反转列一致性。
  • 空值、空字符串、全角半角与大小写标准化。
  • 既有数据回填。
  • 反转索引新增的写放大。
  • 高频后缀导致的低选择率。

4.4 任意位置包含方案

若 KingbaseES 环境已安装并支持 trigram 类扩展,可评估 GIN/GiST 子串索引。由于不同版本的扩展名称、操作符类和支持范围可能不同,不能把 PostgreSQL 示例直接复制到生产。

兼容性检查:

sql 复制代码
SELECT *
FROM sys_available_extensions
WHERE name LIKE '%trgm%';

安装与语法应使用本环境官方手册确认。实施前必须验证:

  • 中文字符如何切分。
  • 两字、三字、英文、数字和符号的索引命中。
  • LIKEILIKE 及相似度操作符是否使用索引。
  • 索引体积和更新成本。
  • 短关键词是否退化为大范围扫描。

若没有合适扩展,则优先收敛业务需求:增加租户、地区、客户等级和状态过滤,限制最短关键词,或把高频类别词改为结构化标签。

4.5 全文检索方案

全文检索适合:

  • 同时搜索客户名称、简称、曾用名、标签。
  • 支持"科技 AND 北京"等组合条件。
  • 需要按相关度排序。
  • 可接受词项匹配而非任意字符子串。

维护方式可以是生成列、触发器或定时重建。示例触发器思路:

sql 复制代码
CREATE OR REPLACE FUNCTION refresh_customer_search_document()
RETURNS TRIGGER AS $$
BEGIN
    NEW.search_document :=
        to_tsvector(
            'simple',
            coalesce(NEW.customer_name, '') || ' ' ||
            coalesce(NEW.short_name, '') || ' ' ||
            coalesce(NEW.former_name, '')
        );
    RETURN NEW;
END;
$$ LANGUAGE plsql;

函数语言及触发器语法需结合实际 KingbaseES 版本调整。

4.6 数据校验

新旧方案必须验证结果差异,而不是只看速度。

前缀结果双向差集:

sql 复制代码
WITH old_result AS (
    SELECT customer_id
    FROM crm_customer
    WHERE customer_name LIKE '华北科%'
),
new_result AS (
    SELECT customer_id
    FROM crm_customer
    WHERE customer_name LIKE '华北科%'
)
SELECT 'old_minus_new' AS diff_type, customer_id
FROM old_result
EXCEPT
SELECT 'old_minus_new', customer_id
FROM new_result

UNION ALL

SELECT 'new_minus_old', customer_id
FROM new_result
EXCEPT
SELECT 'new_minus_old', customer_id
FROM old_result;

全文检索与包含搜索不能要求结果完全一致,应建立业务验收样本:

样本 期望
华北科技有限公司 / "华北科" 前缀命中
华北科技有限公司 / "科技" 包含命中;全文是否命中需按分词验证
城市商业银行股份有限公司 / "有限公司" 后缀命中
北京中科智云 / "中科" 包含命中
旧名:北方科技 / "北方科技" 多字段全文命中

4.7 灰度发布与回退

  1. 新接口增加 search_mode,默认仍走旧 SQL。
  2. 影子流量同时执行新旧查询,只记录结果数量、耗时与差异,不返回新结果。
  3. 前缀查询先灰度 10%,观察 P95、共享块、CPU 和错误率。
  4. 后缀与全文检索独立开关,禁止一次性全部切换。
  5. 新索引保留观察周期,确认写入 TPS 与存储增长可接受。
  6. 发生异常时关闭路由开关,恢复旧 SQL;索引不立即删除。
  7. 若搜索文档维护出现积压,暂停全文路由并补偿重建。

5. 结果对比

5.1 示例测试结果

方案 关键词 计划 平均耗时 P95 共享块 备注
普通索引精确匹配 完整名称 Index Scan 0.22 ms 0.39 ms 8 最稳定
普通索引前缀基线 华北科% Seq Scan 706 ms 812 ms 41,100 排序规则限制
Pattern 前缀索引 华北科% Index Scan 4.8 ms 7.1 ms 132 命中率低
普通后缀查询 %有限公司 Seq Scan 1,620 ms 1,884 ms 42,008 命中 31%
反转列后缀索引 %智云 Index Scan 7.6 ms 11.3 ms 246 低命中后缀有效
普通包含查询 %科技% Seq Scan 1,398 ms 1,603 ms 41,626 扫描全表
GIN 全文检索 科技 Bitmap Heap Scan 32 ms 48 ms 1,260 语义不完全等价

5.2 不能只比较执行时间

优化后的检查项包括:

sql 复制代码
EXPLAIN (ANALYZE, BUFFERS, SETTINGS)
SELECT ...;

重点读以下指标:

  • Index Cond:索引是否真正缩小扫描范围。
  • Filter:是否仍在索引后过滤大量数据。
  • Rows Removed by Filter:候选索引是否匹配查询语义。
  • actual rows:关键词是否属于高命中热点。
  • Buffers:是否减少共享块访问,而非只受热缓存影响。
  • Planning TimeExecution Time:动态生成复杂查询是否增加计划成本。
  • SETTINGS:实验期间是否修改过成本参数或扫描开关。

生产监控还应关注:

sql 复制代码
SELECT queryid,
       calls,
       total_exec_time,
       mean_exec_time,
       rows,
       shared_blks_hit,
       shared_blks_read,
       temp_blks_read,
       temp_blks_written
FROM sys_stat_statements
WHERE query LIKE '%crm_customer%'
ORDER BY total_exec_time DESC;

不同版本统计视图字段可能不同,需按实际环境调整。

5.3 写入成本对比

读性能提升会带来额外写入成本:

索引 读收益 写入影响 适用建议
名称 B-tree 精确、部分前缀 低至中 常规保留
Pattern 前缀索引 前缀范围 前缀高频时采用
反转名称索引 后缀 仅核心后缀需求
Trigram GIN 任意子串 搜索价值高、更新可控
全文 GIN 多字段词项 复杂搜索与相关度
多套索引叠加 多模式 很高 避免无差别叠加

实验中增加两个 GIN 类索引后,批量导入 TPS 下降约 18%,客户名称更新延迟上升约 22%。因此最终方案只保留了前缀索引和全文索引,后缀搜索限制为"租户内、至少 3 个字符、最多返回 100 条",没有为高频"有限公司"建立独立优化路径。


6. 风险与复盘

6.1 前缀匹配的风险

  • C/POSIX 排序规则下,普通索引可能无法支持 LIKE
  • lower(customer_name) LIKE lower(:prefix) || '%' 会改变索引表达式,需要对应表达式索引。
  • 参数写成 LIKE '%' || :keyword || '%' 后,即使关键词本身是前缀,也失去前缀范围条件。
  • 极短前缀如"中%"命中率过高,索引优势会明显下降。

6.2 后缀匹配的风险

  • 反转列增加存储、维护和一致性成本。
  • 高频后缀返回大量数据,索引无法解决结果集过大的根本问题。
  • 中文、英文、空格、括号和全角字符的标准化必须统一。
  • 修改名称时若反转列未同步,可能出现漏查。

6.3 全文检索的风险

  • 词项匹配与字符子串匹配不等价。
  • 中文分词效果取决于词典或扩展,必须使用业务样本验证。
  • GIN 索引体积和更新成本通常高于普通 B-tree。
  • 搜索文档维护延迟会造成新客户暂时不可检索。
  • 相关度排序可能受词频、字段权重和词典变化影响。

6.4 常见错误做法

  1. 看到顺序扫描就强制关闭 enable_seqscan
  2. 为每一种 LIKE 写法都增加一个索引。
  3. 将全文检索描述成 %keyword% 的无损替代。
  4. 只测试一个关键词,不测试热点词、冷门词和短词。
  5. 只看热缓存单次耗时,不看共享块、P95 和写入影响。
  6. 忽略排序规则、大小写规则和中文分词。
  7. 在接口层不限制空字符串与单字符搜索。

6.5 最终决策

本项目最终采用以下组合:

  • 精确名称:普通 B-tree。
  • 租户内名称前缀:tenant_id + pattern 复合索引。
  • 任意位置包含:仅对高权限运营入口开放,并限制最短字符与结果数。
  • 多字段搜索:全文检索,单独维护搜索文档。
  • 后缀查询:不默认开放;特定低命中后缀使用反转列试点。
  • 所有模式:必须先带租户或组织范围,禁止无边界全库搜索。

这次优化最大的收获不是"给 LIKE 建了什么索引",而是把模糊搜索从一条通用 SQL 拆成了多个语义明确的查询产品。数据库可以优化确定的访问模式,却无法用一个索引同时解决精确、前缀、后缀、任意子串和自然语言搜索。


转载自:https://blog.csdn.net/u014727709/article/details/163211072

欢迎 👍点赞✍评论⭐收藏,欢迎指正

相关推荐
阿标在干嘛1 小时前
政策快报平台全文检索的3次升级:从ES到向量检索
大数据·elasticsearch·全文检索
想你依然心痛1 天前
【金仓数据库征文】Oracle到金仓:物化视图迁移与刷新策略重构实践
物化视图·数据校验·金仓数据库·oracle迁移·回退方案·刷新机制·经营分析平台
想你依然心痛1 天前
【金仓数据库征文】Oracle到金仓:分区表迁移及分区裁剪验证
分区表·执行计划·数据校验·金仓数据库·oracle迁移·范围分区·分区裁剪
想你依然心痛1 天前
【金仓数据库征文】Oracle到金仓:DBLINK替代方案与跨库访问设计
dblink·金仓数据库·oracle迁移·安全边界·跨库访问·外部数据封装·故障回退
想你依然心痛2 天前
【金仓数据库征文】Oracle到金仓:序列、触发器与自增键改造实践
触发器·序列·金仓数据库·oracle迁移·自增键·并发验证·回退方案
云边有个稻草人2 天前
金仓数据库技术解析:`WHERE` 里的条件,谁先执行真不是看谁写在前面
性能调优·sql优化·执行计划·金仓数据库·数据库优化器·where子句
想你依然心痛2 天前
【金仓数据库征文】Oracle到金仓:包、过程与函数的兼容改造路线
存储过程·pl/sql·程序包·金仓数据库·oracle迁移·回退方案·兼容改造
金士镧厦门新材2 天前
稀土功能助剂是什么?它如何帮助材料实现性能优化?
全文检索
Elastic 中国社区官方博客3 天前
使用重新设计的 AutoOps 更快地进行 Elasticsearch 问题排查
大数据·运维·前端·人工智能·elasticsearch·搜索引擎·全文检索