diff --git a/.translation-init b/.translation-init index f513d9c7d1..a7083b74fb 100644 --- a/.translation-init +++ b/.translation-init @@ -1 +1 @@ -Translation initialization: 2025-10-23T05:40:09.780391 +Translation initialization: 2025-10-23T15:42:46.376452 diff --git a/docs/cn/guides/00-products/01-dee/10-enterprise-features.md b/docs/cn/guides/00-products/01-dee/10-enterprise-features.md index 92ae832312..64c864dd89 100644 --- a/docs/cn/guides/00-products/01-dee/10-enterprise-features.md +++ b/docs/cn/guides/00-products/01-dee/10-enterprise-features.md @@ -4,75 +4,75 @@ title: 企业版功能 import DatabendTable from '@site/src/components/DatabendTable'; -本页面列出了当前可用的企业版功能。如需使用这些功能,您必须拥有企业版或试用版许可证。更多详情,请参阅 [Databend 许可证](20-license.md)。 +本页面提供了可用企业版功能的最新列表。要访问这些功能,您需要企业版或试用许可证。有关更多详细信息,请参阅 [Databend 许可证](20-license.md)。 ### 企业版功能列表 -| 功能 | 类别 | 描述 | -| -------------------------------------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [审计追踪 (Audit Trail)](/guides/security/audit-trail) | 安全与合规 | 通过全面的审计日志监控数据库活动,满足合规与安全需求。 | -| [脱敏策略 (Masking Policy)](/sql/sql-commands/ddl/mask-policy/) | 安全与合规 | 基于角色的脱敏策略,保护敏感数据。 | -| 存储加密 (Storage Encryption) | 安全与合规 | 使用服务托管、KMS 或客户管理的密钥对静态数据进行加密。 | -| [BendSave](/guides/data-management/data-recovery#bendsave) | 灾难恢复 | 备份并恢复整个 Databend 集群数据,用于灾难恢复。 | -| [故障安全 (Fail-Safe)](/guides/security/fail-safe) | 灾难恢复 | 从兼容 S3 的对象存储中恢复丢失或误删的数据。 | -| [聚合索引 (Aggregating Index)](/sql/sql-commands/ddl/aggregating-index) | 查询性能 | 通过预计算并索引的聚合结果加速查询。 | -| [全文索引 (Full-Text Index)](/guides/performance/fulltext-index) | 查询性能 | 利用倒排索引和相关性评分实现极速文本搜索。 | -| [Ngram 索引 (Ngram Index)](/guides/performance/ngram-index) | 查询性能 | 通过通配符搜索加速 LIKE 模式匹配查询。 | -| [虚拟列 (Virtual Column)](/sql/sql-commands/ddl/virtual-column) | 查询性能 | 对 VARIANT 数据零配置性能优化,自动加速 JSON 查询。 | -| [动态列 (Dynamic Column)](/sql/sql-commands/ddl/table/ddl-create-table#computed-columns) | 查询性能 | 通过存储或虚拟计算模式,从标量表达式自动生成列。 | -| [Python UDF](/sql/sql-commands/ddl/udf/ddl-create-function-embedded#python) | 高级分析 | 使用内置处理器在 SQL 查询中执行 Python 代码。 | -| [ATTACH TABLE](/sql/sql-commands/ddl/table/attach-table) | 数据共享 | 创建指向现有表数据的只读链接,实现跨环境零拷贝访问。 | -| [流 (Stream)](/sql/sql-commands/ddl/stream) | 变更数据捕获 | 跟踪并捕获表变更,用于增量数据处理。 | -| [清理临时文件 (Vacuum Temp Files)](/sql/sql-commands/administration-cmds/vacuum-temp-files) | 存储管理 | 清理临时文件(连接、聚合、排序溢出文件),释放存储空间。 | -| [清理已删除表 (Vacuum Dropped Table)](/sql/sql-commands/ddl/table/vacuum-drop-table) | 存储管理 | 删除已删除表的数据文件以优化存储,并提供恢复选项。 | -| [清理历史数据 (Vacuum Historical Data)](/sql/sql-commands/ddl/table/vacuum-table) | 存储管理 | 移除孤立的段和块文件,深度清理存储空间。 | - -## Databend 社区版 (Community) vs. 企业版 (Enterprise) - -本节对比 Databend 社区版 (Community) 与 Databend 企业版 (Enterprise) 在关键能力上的差异: +| 功能 | 类别 | 描述 | +|------|------|------| +| [审计追踪 (Audit Trail)](/guides/security/audit-trail) | 安全与合规 | 通过全面的审计日志监控数据库活动,满足合规性和安全性要求。 | +| [掩码策略 (Masking Policy)](/sql/sql-commands/ddl/mask-policy/) | 安全与合规 | 通过基于角色的掩码策略保护敏感数据。 | +| 存储加密 (Storage Encryption) | 安全与合规 | 使用服务托管、KMS 或客户托管密钥对静态数据进行加密。 | +| [BendSave](/guides/data-management/data-recovery#bendsave) | 灾难恢复 | 备份和恢复整个 Databend 集群数据,实现灾难恢复。 | +| [故障安全 (Fail-Safe)](/guides/security/fail-safe) | 灾难恢复 | 从 S3 兼容的对象存储中恢复丢失或意外删除的数据。 | +| [聚合索引 (Aggregating Index)](/sql/sql-commands/ddl/aggregating-index) | 查询性能 | 通过预计算和索引聚合来加速查询。 | +| [全文索引 (Full-Text Index)](/guides/performance/fulltext-index) | 查询性能 | 使用倒排索引和相关性评分实现极速文本搜索。 | +| [Ngram 索引 (Ngram Index)](/guides/performance/ngram-index) | 查询性能 | 通过通配符搜索加速 LIKE 模式匹配查询。 | +| [虚拟列 (Virtual Column)](/sql/sql-commands/ddl/virtual-column) | 查询性能 | 自动加速 JSON 查询,为 VARIANT 数据提供零配置性能优化。 | +| [动态列 (Dynamic Column)](/sql/sql-commands/ddl/table/ddl-create-table#computed-columns) | 查询性能 | 通过存储或虚拟计算模式,从标量表达式自动生成列。 | +| [Python UDF](/sql/sql-commands/ddl/udf/ddl-create-function-embedded#python) | 高级分析 | 使用内置处理程序在 SQL 查询中执行 Python 代码。 | +| [ATTACH TABLE](/sql/sql-commands/ddl/table/attach-table) | 数据共享 | 创建指向现有表数据的只读链接,实现跨环境的零拷贝访问。 | +| [流 (Stream)](/sql/sql-commands/ddl/stream) | 变更数据捕获 | 跟踪并捕获表变更,支持增量数据处理。 | +| [清理临时文件 (Vacuum Temp Files)](/sql/sql-commands/administration-cmds/vacuum-temp-files) | 存储管理 | 清理临时文件(连接、聚合、排序溢出)以释放存储空间。 | +| [清理已删除表 (Vacuum Dropped Table)](/sql/sql-commands/ddl/table/vacuum-drop-table) | 存储管理 | 删除已删除表的数据文件以优化存储,并提供恢复选项。 | +| [清理历史数据 (Vacuum Historical Data)](/sql/sql-commands/ddl/table/vacuum-table) | 存储管理 | 删除孤立的段和块文件,深度清理存储空间。 | + +## Databend 社区版 vs. 企业版 + +本节对比 Databend 社区版与企业版在关键功能上的差异: ### 核心数据库引擎 -### 企业级安全与合规 +### 企业安全与合规 @@ -80,13 +80,13 @@ tbody={[ @@ -94,11 +94,11 @@ tbody={[ @@ -106,27 +106,27 @@ tbody={[ -### 企业级存储与备份 +### 企业存储与备份 @@ -134,13 +134,13 @@ tbody={[ @@ -148,7 +148,7 @@ tbody={[ -### 企业级支持 +### 企业支持 +/> \ No newline at end of file diff --git a/docs/cn/guides/51-ai-functions/01-external-functions.md b/docs/cn/guides/51-ai-functions/01-external-functions.md index 338283ac17..6b45db29a1 100644 --- a/docs/cn/guides/51-ai-functions/01-external-functions.md +++ b/docs/cn/guides/51-ai-functions/01-external-functions.md @@ -1,17 +1,17 @@ --- -title: 使用外部函数自定义 AI/ML +title: 使用外部函数(External Functions)自定义 AI/ML --- -# 使用外部函数自定义 AI/ML +# 使用外部函数(External Functions)自定义 AI/ML -通过将 Databend 与您自己的基础设施连接,构建强大的 AI/ML 能力。外部函数(External Function)让您能够部署自定义模型、利用 GPU 加速,并与任何 ML 框架集成,同时确保数据安全。 +通过将 Databend 与您自己的基础设施连接,构建强大的 AI/ML 能力。外部函数(External Functions)让您能够部署自定义模型、利用 GPU 加速,并与任何 ML 框架集成,同时确保数据安全。 ## 核心能力 | 功能 | 优势 | |---------|----------| | **自定义模型** | 使用任何开源或专有的 AI/ML 模型 | -| **GPU 加速** | 部署在配备 GPU 的机器上以加快推理速度 | +| **GPU 加速** | 在配备 GPU 的机器上部署以实现更快的推理 | | **数据隐私** | 将数据保留在您的基础设施内 | | **可扩展性** | 独立扩展和资源优化 | | **灵活性** | 支持任何编程语言和 ML 框架 | @@ -20,36 +20,36 @@ title: 使用外部函数自定义 AI/ML 1. **创建 AI 服务器**:使用 Python 和 [databend-udf](https://pypi.org/project/databend-udf) 构建您的 AI/ML 服务器 2. **注册函数**:使用 `CREATE FUNCTION` 将您的服务器连接到 Databend -3. **在 SQL 中使用**:直接在 SQL 查询中调用您的自定义 AI 函数 +3. **在 SQL 中使用**:直接在 SQL 查询(Query)中调用您的自定义 AI 函数 ## 示例:文本嵌入函数 ```python -# 简单的嵌入 UDF 服务器演示 +# Simple embedding UDF server demo from databend_udf import udf, UDFServer from sentence_transformers import SentenceTransformer -# 加载预训练模型 -model = SentenceTransformer('all-mpnet-base-v2') # 768 维向量 +# Load pre-trained model +model = SentenceTransformer('all-mpnet-base-v2') # 768-dimensional vectors @udf( input_types=["STRING"], result_type="ARRAY(FLOAT)", ) def ai_embed_768(inputs: list[str], headers) -> list[list[float]]: - """为输入文本生成 768 维嵌入""" + """为输入文本生成 768 维嵌入向量""" try: - # 单批次处理输入 + # 在单个批次中处理输入 embeddings = model.encode(inputs) # 转换为列表格式 return [embedding.tolist() for embedding in embeddings] except Exception as e: print(f"Error generating embeddings: {e}") - # 如果出错,则返回空列表 + # 出错时返回空列表 return [[] for _ in inputs] if __name__ == '__main__': - print("正在端口 8815 上启动嵌入 UDF 服务器...") + print("Starting embedding UDF server on port 8815...") server = UDFServer("0.0.0.0:8815") server.add_function(ai_embed_768) server.serve() @@ -63,7 +63,7 @@ CREATE OR REPLACE FUNCTION ai_embed_768 (STRING) HANDLER = 'ai_embed_768' ADDRESS = 'https://your-ml-server.example.com'; --- 在查询中使用自定义嵌入 +-- 在查询中使用自定义嵌入函数 SELECT id, title, @@ -78,5 +78,5 @@ LIMIT 5; ## 了解更多 -- **[外部函数指南](/guides/ai-functions/external-functions)** - 完整的设置和部署说明 -- **[Databend Cloud](https://databend.cn)** - 使用免费账户试用外部函数 +- **[外部函数(External Functions)指南](/guides/ai-functions/external-functions)** - 完整的设置和部署说明 +- **[Databend Cloud](https://databend.cn)** - 使用免费账户试用外部函数(External Functions) \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-sql-analytics.md b/docs/cn/guides/54-query/00-sql-analytics.md new file mode 100644 index 0000000000..ef5673c240 --- /dev/null +++ b/docs/cn/guides/54-query/00-sql-analytics.md @@ -0,0 +1,277 @@ +--- +title: SQL 分析 +--- + +> **场景:** EverDrive Smart Vision 分析师整理了一组共享的驾驶会话(Drive Session)和关键帧(Key Frame),使每个下游工作负载(Workload)都能查询相同的 ID,而无需在系统之间复制数据。 + +本教程构建了一个微型 **EverDrive Smart Vision** 数据集(Dataset),并展示了 Databend 的单一优化器(Query Optimizer)如何在其余指南中工作。您在此处创建的每个 ID(`SES-20240801-SEA01`、`FRAME-0001` …)都会在 JSON、向量(Vector)、地理(Geo)和 ETL 演练中重复出现,形成一致的自动驾驶故事。 + +## 1. 创建示例表 +两个表捕获测试会话和从行车记录仪视频中提取的重要帧。 + +```sql +CREATE OR REPLACE TABLE drive_sessions ( + session_id VARCHAR, + vehicle_id VARCHAR, + route_name VARCHAR, + start_time TIMESTAMP, + end_time TIMESTAMP, + weather VARCHAR, + camera_setup VARCHAR +); + +CREATE OR REPLACE TABLE frame_events ( + frame_id VARCHAR, + session_id VARCHAR, + frame_index INT, + captured_at TIMESTAMP, + event_type VARCHAR, + risk_score DOUBLE +); + +INSERT INTO drive_sessions VALUES + ('SES-20240801-SEA01', 'VEH-01', 'Seattle → Bellevue → Seattle', '2024-08-01 09:00', '2024-08-01 10:10', 'Sunny', 'Dual 1080p'), + ('SES-20240802-SEA02', 'VEH-02', 'Downtown Night Loop', '2024-08-02 20:15', '2024-08-02 21:05', 'Light Rain','Night Vision'), + ('SES-20240803-SEA03', 'VEH-03', 'Harbor Industrial Route', '2024-08-03 14:05', '2024-08-03 15:30', 'Overcast', 'Thermal + RGB'); + +INSERT INTO frame_events VALUES + ('FRAME-0001', 'SES-20240801-SEA01', 120, '2024-08-01 09:32:15', 'SuddenBrake', 0.82), + ('FRAME-0002', 'SES-20240801-SEA01', 342, '2024-08-01 09:48:03', 'CrosswalkPedestrian', 0.67), + ('FRAME-0003', 'SES-20240802-SEA02', 88, '2024-08-02 20:29:41', 'NightLowVisibility', 0.59), + ('FRAME-0004', 'SES-20240802-SEA02', 214, '2024-08-02 20:48:12', 'EmergencyVehicle', 0.73), + ('FRAME-0005', 'SES-20240803-SEA03', 305, '2024-08-03 15:02:44', 'CyclistOvertake', 0.64); +``` + +> 需要复习表 DDL?请参阅 [CREATE TABLE](/sql/sql-commands/ddl/table/ddl-create-table)。 + +--- + +## 2. 过滤最近的会话 +将分析重点放在最近的驾驶上。 + +```sql +WITH recent_sessions AS ( + SELECT * + FROM drive_sessions + WHERE start_time >= DATEADD('day', -7, CURRENT_TIMESTAMP) +) +SELECT * +FROM recent_sessions +ORDER BY start_time DESC; +``` + +提前过滤可使后续的连接(Join)和聚合(Aggregation)更快。文档:[WHERE & CASE](/sql/sql-commands/query-syntax/query-select#where-clause)。 + +--- + +## 3. JOIN(连接) +### INNER JOIN ... USING(内连接) +将会话元数据(Metadata)与帧级事件结合。 + +```sql +WITH recent_events AS ( + SELECT * + FROM frame_events + WHERE captured_at >= DATEADD('day', -7, CURRENT_TIMESTAMP) +) +SELECT e.frame_id, + e.captured_at, + e.event_type, + e.risk_score, + s.vehicle_id, + s.route_name, + s.weather +FROM recent_events e +JOIN drive_sessions s USING (session_id) +ORDER BY e.captured_at; +``` + +### NOT EXISTS(反连接) +查找缺少会话元数据的事件。 + +```sql +SELECT frame_id +FROM frame_events e +WHERE NOT EXISTS ( + SELECT 1 + FROM drive_sessions s + WHERE s.session_id = e.session_id +); +``` + +### LATERAL FLATTEN(JSON 展开) +将事件与存储在 JSON 负载(Payload)中的检测对象结合。 + +```sql +SELECT e.frame_id, + obj.value['type']::STRING AS object_type +FROM frame_events e +JOIN frame_payloads p USING (frame_id), + LATERAL FLATTEN(p.payload['objects']) AS obj; +``` + +更多模式:[JOIN 参考](/sql/sql-commands/query-syntax/query-join)。 + +--- + +## 4. GROUP BY(分组) +### GROUP BY route_name, event_type +标准 `GROUP BY` 用于比较路线和事件类型。 + +```sql +WITH recent_events AS ( + SELECT * + FROM frame_events + WHERE captured_at >= DATEADD('week', -4, CURRENT_TIMESTAMP) +) +SELECT route_name, + event_type, + COUNT(*) AS event_count, + AVG(risk_score) AS avg_risk +FROM recent_events +JOIN drive_sessions USING (session_id) +GROUP BY route_name, event_type +ORDER BY avg_risk DESC, event_count DESC; +``` + +### GROUP BY ROLLUP +添加路线小计和总计。 + +```sql +SELECT route_name, + event_type, + COUNT(*) AS event_count, + AVG(risk_score) AS avg_risk +FROM frame_events +JOIN drive_sessions USING (session_id) +GROUP BY ROLLUP(route_name, event_type) +ORDER BY route_name NULLS LAST, event_type; +``` + +### GROUP BY CUBE +生成路线和事件类型的所有组合。 + +```sql +SELECT route_name, + event_type, + COUNT(*) AS event_count, + AVG(risk_score) AS avg_risk +FROM frame极events +JOIN drive_sessions USING (session_id) +GROUP BY CUBE(route_name, event_type) +ORDER BY route_name NULLS LAST, event_type; +``` + +--- + +## 5. WINDOW FUNCTION(窗口函数) +### SUM(...) OVER(累计总和) +使用累计 `SUM` 跟踪每次驾驶的累积风险。 + +```sql +WITH session_event_scores AS ( + SELECT session极id, + captured_at, + risk_score + FROM frame_events +) +SELECT session_id, + captured_at, + risk_score, + SUM(risk_score) OVER ( + PARTITION BY session_id + ORDER BY captured_at + ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + ) AS cumulative_risk +FROM session_event_scores +ORDER BY session_id, captured_at; +``` + +### AVG(...) OVER(移动平均) +显示最近三个事件的风险移动平均值: + +```sql +WITH session_event_scores AS ( + SELECT session_id, + captured_at, + risk_score + FROM frame_events +) +SELECT session_id, + captured_at, + risk_score, + AVG(risk_score) OVER ( + PARTITION BY session_id + ORDER BY captured极at + ROWS BETWEEN 3 PRECEDING AND CURRENT ROW + ) AS moving_avg_risk +FROM session_event_scores +ORDER BY session_id, captured_at; +``` + +窗口函数允许您内联表达滚动总计或平均值。完整列表:[窗口函数](/sql/sql-functions/window-functions)。 + +--- + +## 6. 聚合索引(Aggregating Index)加速 +使用[聚合索引](/guides/performance/aggregating-index)缓存繁重的汇总,使仪表盘保持快速响应。 + +```sql +CREATE OR REPLACE AGGREGATING INDEX idx_route_event_summary ON frame_events +AS +SELECT session_id, + event_type, + COUNT(*) AS event_count, + AV极G(risk_score) AS avg_risk +FROM frame_events +GROUP BY session_id, event_type; +``` + +现在运行与之前相同的汇总查询——优化器将自动从索引中提取结果: + +```sql +SELECT s.route_name, + e.event_type, + COUNT(*) AS event_count, + AVG(e.risk_score) AS avg_risk +FROM frame_events e +JOIN drive_sessions s USING (session_id) +WHERE s.start_time >= DATEADD('week', -8, CURRENT_TIMESTAMP) +GROUP BY s.route_name, e.event_type +ORDER BY avg_risk DESC; +``` + +使用 `EXPLAIN` 查看语句,可以看到 `AggregatingIndex` 节点而不是全表扫描(Full Scan)。Databend 会在新帧到达时保持索引的新鲜度,无需额外的 ETL 作业即可提供亚秒级仪表盘。 + +--- + +## 7. 存储过程(Stored Procedure)自动化 +您还可以将报告逻辑包装在存储过程中,以便在计划作业期间按预期方式运行。 + +```sql +CREATE OR REPLACE PROCEDURE generate_weekly_route_report(days_back INT) +RETURNS TABLE(route_name VARCHAR, event_count BIGINT, avg_risk DOUBLE) +LANGUAGE SQL +AS +$$ +BEGIN + RETURN TABLE ( + SELECT s.route_name, + COUNT(*) AS event_count, + AVG(e.risk_score) AS avg_risk + FROM frame_events e + JOIN drive_sessions s USING (session_id) + WHERE e.captured_at >= DATEADD('day', -days_back, CURRENT_TIMESTAMP) + GROUP BY s.route_name + ); +END; +$$; + +CALL PROCEDURE generate_weekly_route_report(28); +``` + +在笔记本、ETL 任务或自动警报中直接使用返回的结果集(Result Set)。了解更多:[存储过程脚本](/sql/stored-procedure-scripting)。 + +--- + +您现在拥有一个完整的循环:摄取会话数据、过滤、连接、聚合、加速繁重查询、随时间趋势分析和发布。交换过滤器或连接以将相同的方法应用于其他智能驾驶 KPI,如驾驶员评分、传感器退化或算法比较。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-json-search.md b/docs/cn/guides/54-query/01-json-search.md new file mode 100644 index 0000000000..7142870e93 --- /dev/null +++ b/docs/cn/guides/54-query/01-json-search.md @@ -0,0 +1,140 @@ +--- +title: JSON 与搜索 +--- + +> **场景:** EverDrive Smart Vision 的感知服务为每个观测帧生成 JSON 负载,安全分析师需要在不将数据移出 Databend 的情况下搜索检测结果。 + +EverDrive 的感知流水线生成 JSON 负载,我们使用类似 Elasticsearch 的语法进行查询。通过将负载存储为 VARIANT 类型并在创建表时声明倒排索引(Inverted Index),Databend 允许您直接在数据上运行 Lucene `QUERY` 过滤器。 + +## 1. 创建示例表 +每个帧携带来自感知模型的结构化元数据(边界框、速度、分类)。 + +```sql +CREATE OR REPLACE TABLE frame_payloads ( + frame_id VARCHAR, + run_stage VARCHAR, + payload VARIANT, + logged_at TIMESTAMP, + INVERTED INDEX idx_frame_payloads(payload) +); + +INSERT INTO frame_payloads VALUES + ('FRAME-0001', 'detection', PARSE_JSON('{ + "objects": [ + {"type":"vehicle","bbox":[545,220,630,380],"confidence":0.94}, + {"type":"pedestrian","bbox":[710,200,765,350],"confidence":0.88} + ], + "ego": {"speed_kmh": 32.5, "accel": -2.1} + }'), '2024-08-01 09:32:16'), + ('FRAME-0002', 'detection', PARSE_JSON('{ + "objects": [ + {"type":"pedestrian","bbox":[620,210,670,360],"confidence":0.91} + ], + "scene": {"lighting":"daytime","weather":"sunny"} + }'), '2024-08-01 09:48:04'), + ('FRAME-0003', 'tracking', PARSE_JSON('{ + "objects": [ + {"type":"vehicle","speed_kmh": 18.0,"distance_m": 6.2}, + {"type":"emergency_vehicle","sirens":true} + ], + "scene": {"lighting":"night","visibility":"low"} + }'), '2024-08-02 20:29:42'); +``` + +## 2. 选择 JSON 路径 +查看负载以确认结构。 + +```sql +SELECT frame_id, + payload['objects'][0]['type']::STRING AS first_object, + payload['ego']['speed_kmh']::DOUBLE AS ego_speed, + payload['scene']['lighting']::STRING AS lighting +FROM frame_payloads +ORDER BY logged_at; +``` + +使用 `::STRING` / `::DOUBLE` 进行类型转换可将 JSON 值暴露给常规 SQL 过滤器。Databend 还通过 `QUERY` 函数支持在此数据之上进行类似 Elasticsearch 的搜索——通过在变体字段前加上列名来引用它们(例如 `payload.objects.type`)。更多提示:[半结构化数据](https://docs.databend.cn/guides/load-data/load-semistructured/load-ndjson)。 + +--- + +## 3. 类似 Elasticsearch 的搜索 +`QUERY` 使用 Elasticsearch/Lucene 语法,因此您可以组合布尔逻辑、范围、权重提升和列表。以下是在 EverDrive 负载上的几种模式: + +### 数组匹配 +查找检测到行人的帧: + +```sql +SELECT frame_id +FROM frame_payloads +WHERE QUERY('payload.objects.type:pedestrian') +ORDER BY logged_at DESC +LIMIT 10; +``` + +### 布尔 AND +车辆行驶速度超过 30 km/h **且**检测到行人: + +```sql +SELECT frame_id, + payload['ego']['speed_kmh']::DOUBLE AS ego_speed +FROM frame_payloads +WHERE QUERY('payload.objects.type:pedestrian AND payload.ego.speed_kmh:[30 TO *]') +ORDER BY ego_speed DESC; +``` + +### 布尔 OR / 列表 +夜间驾驶遇到紧急车辆或骑行者: + +```sql +SELECT frame_id +FROM frame_payloads +WHERE QUERY('payload.scene.lighting:night AND payload.objects.type:(emergency_vehicle OR cyclist)'); +``` + +### 数值范围 +速度在 10–25 km/h 之间(包含边界)或严格在 25–40 km/h 之间: + +```sql +SELECT frame_id, + payload['ego']['speed_kmh'] AS speed +FROM frame_payloads +WHERE QUERY('payload.ego.speed_kmh:[10 TO 25] OR payload.ego.speed_kmh:{25 TO 40}') +ORDER BY speed; +``` + +### 权重提升 +优先处理同时出现行人和车辆的帧,但强调行人项: + +```sql +SELECT frame_id, + SCORE() AS relevance +FROM frame_payloads +WHERE QUERY('payload.objects.type:pedestrian^2 AND payload.objects.type:vehicle') +ORDER BY relevance DESC +LIMIT 10; +``` + +查看[搜索函数](https://docs.databend.cn/sql/sql-functions/search-functions)了解 `QUERY`、`SCORE()` 和相关辅助函数支持的完整 Elasticsearch 语法。 + +--- + +## 4. 交叉引用帧事件 +将查询结果与分析指南中创建的帧级风险评分进行关联。 + +```sql +WITH risky_frames AS ( + SELECT frame_id, + payload['ego']['speed_kmh']::DOUBLE AS ego_speed + FROM frame_payloads + WHERE QUERY('payload.objects.type:pedestrian AND payload.ego.speed_kmh:[30 TO *]') +) +SELECT r.frame_id, + e.event_type, + e.risk_score, + r.ego_speed +FROM risky_frames r +JOIN frame_events e USING (frame_id) +ORDER BY e.risk_score DESC; +``` + +由于 `frame_id` 在表之间共享,您可以立即从原始负载跳转到精选分析。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-vector-db.md b/docs/cn/guides/54-query/02-vector-db.md new file mode 100644 index 0000000000..9b56245372 --- /dev/null +++ b/docs/cn/guides/54-query/02-vector-db.md @@ -0,0 +1,100 @@ +--- +title: 向量搜索(Vector Search) +--- + +> **场景:** EverDrive Smart Vision 为风险帧附加紧凑的视觉嵌入向量(Embedding),以便调查团队可以直接在 Databend 中检索相似情况。 + +每个提取的帧都附带视觉嵌入向量,方便感知工程师发现相似场景。本指南展示如何插入这些向量并在相同的 EverDrive ID 上执行语义搜索。 + +## 1. 创建示例表 +为提升可读性,我们使用四维向量存储紧凑示例。在生产环境中,您可能需要保存来自 CLIP 或自监督模型的 512 维或 1536 维嵌入向量。 + +```sql +CREATE OR REPLACE TABLE frame_embeddings ( + frame_id VARCHAR, + session_id VARCHAR, + embedding VECTOR(4), + model_version VARCHAR, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + VECTOR INDEX idx_frame_embeddings(embedding) distance='cosine' +); + +INSERT INTO frame_embeddings VALUES + ('FRAME-0001', 'SES-20240801-SEA01', [0.18, 0.42, 0.07, 0.12]::VECTOR(4), 'clip-mini-v1', DEFAULT), + ('FRAME-0002', 'SES-20240801-SEA01', [0.20, 0.38, 0.12, 0.18]::VECTOR(4), 'clip-mini-v1', DEFAULT), + ('FRAME-0003', 'SES-20240802-SEA02', [0.62, 0.55, 0.58, 0.61]::VECTOR(4), 'night-fusion-v2', DEFAULT), + ('FRAME-0004', 'SES-20240802-SEA02', [0.57, 0.49, 0.52, 0.55]::VECTOR(4), 'night-fusion-v2', DEFAULT); +``` + +文档:[向量数据类型(Vector)](/sql/sql-reference/data-types/vector) 和 [向量索引(Vector Index)](/sql/sql-reference/data-types/vector#vector-indexing)。 + +--- + +## 2. COSINE_DISTANCE 搜索 +搜索与 `FRAME-0001` 最相似的帧。 + +```sql +WITH query_embedding AS ( + SELECT embedding + FROM frame_embeddings + WHERE frame_id = 'FRAME-0001' + LIMIT 1 +) +SELECT e.frame_id, + e.session_id, + cosine_distance(e.embedding, q.embedding) AS distance +FROM frame_embeddings e +CROSS JOIN query_embedding q +ORDER BY distance +LIMIT 3; +``` + +余弦距离计算利用先前创建的 HNSW 索引(Index),优先返回最相似的帧。 + +--- + +## 3. WHERE 过滤 + 相似度 +将相似度搜索与传统谓词结合以缩小结果范围。 + +```sql +WITH query_embedding AS ( + SELECT embedding + FROM frame_embeddings + WHERE frame_id = 'FRAME-0003' + LIMIT 1 +) +SELECT e.frame_id, + cosine_distance(e.embedding, q.embedding) AS distance +FROM frame_embeddings e +CROSS JOIN query_embedding q +WHERE e.session_id = 'SES-20240802-SEA02' +ORDER BY distance; +``` + +--- + +## 4. 连接(JOIN)语义 + 风险元数据 +将语义搜索结果与风险评分或检测负载关联,以支持更深入的调查分析。 + +```sql +WITH query_embedding AS ( + SELECT embedding FROM frame_embeddings WHERE frame_id = 'FRAME-0001' LIMIT 1 + ), + similar_frames AS ( + SELECT frame_id, + cosine_distance(e.embedding, q.embedding) AS distance + FROM frame_embeddings e + CROSS JOIN query_embedding q + ORDER BY distance + LIMIT 5 + ) +SELECT sf.frame_id, + fe.event_type, + fe.risk_score, + sf.distance +FROM similar_frames sf +LEFT JOIN frame_events fe USING (frame_id) +ORDER BY sf.distance; +``` + +该混合视图(View)可呈现“视觉特征与 FRAME-0001 相似且触发了高风险事件”的帧。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/03-geo-analytics.md b/docs/cn/guides/54-query/03-geo-analytics.md new file mode 100644 index 0000000000..b566a0a555 --- /dev/null +++ b/docs/cn/guides/54-query/03-geo-analytics.md @@ -0,0 +1,139 @@ +--- +title: 地理分析(Geo Analytics) +--- + +> **场景:** EverDrive Smart Vision 为每个关键帧记录 GPS 坐标,以便运营团队能够绘制城市范围内的危险驾驶热点区域。 + +每一帧都标记了 GPS 坐标,因此我们可以在城市范围内绘制危险情况的分布图。本指南添加了一个地理空间表,并演示了使用相同 EverDrive 会话 ID 的空间过滤器、多边形和 H3 分桶(Bucketing)。 + +## 1. 创建示例表 +每条记录代表捕获关键帧时的本车位置。将坐标存储为 `GEOMETRY` 类型,以便您可以重用本工作负载中展示的 `ST_X`、`ST_Y` 和 `HAVERSINE` 等函数。 + +```sql +CREATE OR REPLACE TABLE drive_geo ( + frame_id VARCHAR, + session_id VARCHAR, + location GEOMETRY, + speed_kmh DOUBLE, + heading_deg DOUBLE +); + +INSERT INTO drive_geo VALUES + ('FRAME-0001', 'SES-20240801-SEA01', TO_GEOMETRY('SRID=4326;POINT(-122.3321 47.6062)'), 28.0, 90), + ('FRAME-0002', 'SES-20240801-SEA01', TO_GEOMETRY('SRID=4326;POINT(-122.3131 47.6105)'), 35.4, 120), + ('FRAME-0003', 'SES-20240802-SEA02', TO_GEOMETRY('SRID=4326;POINT(-122.3419 47.6205)'), 18.5, 45), + ('FRAME-0004', 'SES-20240802-SEA02', TO_GEOMETRY('SRID=4326;POINT(-122.3490 47.6138)'), 22.3, 60), + ('FRAME-0005', 'SES-20240803-SEA03', TO_GEOMETRY('SRID=4326;POINT(-122.3610 47.6010)'), 30.极 210); +``` + +文档:[地理空间数据类型](/sql/sql-reference/data-types/geospatial)。 + +--- + +## 2. ST_DISTANCE 半径过滤 +`ST_DISTANCE` 函数测量几何图形之间的距离。将帧位置和热点都转换为 Web 墨卡托投影(SRID 3857),使结果以米为单位表示,然后过滤到 500 米范围内。 + +```sql +SELECT g.frame_id, + g.session_id, + e.event_type, + e.极_score, + ST_DISTANCE( + ST_TRANSFORM(g.location, 3857), + ST_TRANSFORM(TO_GEOMETRY('SRID=4326;POINT(-122.3350 47.6080)'), 3857) + ) AS meters_from_hotspot +FROM drive_geo g +JOIN frame_events e USING (frame_id) +WHERE ST极STANCE( + ST_TRANSFORM(g.location, 3857), + ST_TRANSFORM(TO_GEOMETRY('SRID=4326;POINT(-122.3350 47.6080)'), 3857) + ) <= 500 +ORDER BY meters_from_hotspot; +``` + +需要原始几何图形进行调试?在投影中添加 `ST_ASTEXT(g.location)`。更喜欢直接的大圆距离计算?换用 `HAVERSINE` 函数,它对 `ST_X`/`ST_Y` 坐标进行操作。 + +--- + +## 3. ST_CONTAINS 多边形过滤 +检查事件是否发生在定义的安全区域内(例如学校区域)。 + +```sql +WITH school_zone AS ( + SELECT TO_GEOMETRY('SRID=4326;POLYGON(( + -122.3415 47.6150, + -122.3300 47.6150, + -极.3300 47.6070, + -122.3415 47.6070, + -122.3415 47.6150 + ))') AS poly +) +SELECT g.frame_id, + g.session_id, + e.event_type +FROM drive_geo g +JOIN frame_events e USING (frame_id) +CROSS JOIN school_zone +WHERE ST_CONTAINS(poly, g.location); +``` + +--- + +## 4. GEO_TO_H3 热力图 +按六边形单元聚合事件以构建路线热力图。 + +```sql +SELECT GEO_TO_H3(ST_X(location), ST_Y(location), 8) AS h3_cell, + COUNT(*) AS frame_count, + AVG(e.极_score) AS avg_极 +FROM drive_geo +JOIN frame_events e USING (frame极) +GROUP BY h3_cell +ORDER BY avg_极 DESC; +``` + +文档:[H3 函数](/sql/sql-functions/geospatial-functions#h3-indexing--conversion)。 + +--- + +## 5. ST_DISTANCE + JSON 查询 +结合空间距离检查与丰富的检测元数据(来自 JSON 指南)以构建精确的警报。 + +```sql +WITH near_intersection AS ( + SELECT frame_id + FROM drive_geo + WHERE ST_DISTANCE( + ST_TRANSFORM(location, 3857), + ST_TRANSFORM(TO_GEOMETRY('SRID=4326;POINT(-122.3410 47.6130)'), 3857) + ) <= 200 +) +SELECT n.frame_id, + p.payload['objects'][0]['type']::STRING AS first_object, + e.event_type, + e.极_score +FROM near_intersection n +JOIN frame_payloads p USING (frame_id) +JOIN frame_events e USING (frame_id) +WHERE QUERY('payload.objects.type:pedestrian'); +``` + +空间过滤器、JSON 操作符和经典 SQL 都在一条语句中运行。 + +--- + +## 6. 创建视图热力图 +将六边形级别的摘要导出到可视化工具或地图图层。 + +```sql +CREATE OR REPLACE VIEW v_route_heatmap AS ( + SELECT GEO_TO_H3(ST_X(location), ST_Y(location), 7) AS h3_cell, + COUNT(*) AS frames, + AVG(e.极_score) AS avg_极 + FROM drive_geo + JOIN frame_events e USING (frame_id) + GROUP BY h3_cell +); +``` + +下游系统可以直接查询 `v_route_heatmap` 以在地图上渲染风险热点,而无需重新处理原始遥测数据。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/04-lakehouse-etl.md b/docs/cn/guides/54-query/04-lakehouse-etl.md new file mode 100644 index 0000000000..c45d6068d0 --- /dev/null +++ b/docs/cn/guides/54-query/04-lakehouse-etl.md @@ -0,0 +1,186 @@ +--- +title: 湖仓 ETL +--- + +> **场景:** EverDrive Smart Vision 的数据工程团队将每批道路测试数据导出为 Parquet 文件,以便统一工作负载可以在 Databend 中加载、查询和丰富相同的遥测数据。 + +EverDrive 的数据摄取流程非常简单: + +``` +对象存储导出(例如 Parquet)→ 暂存区(Stage)→ COPY INTO → (可选)流(Stream)和任务(Task) +``` + +调整存储桶路径/凭证(如果格式不同,请将 Parquet 替换为实际格式),然后粘贴以下命令。所有语法与官方[加载数据指南](/cn/guides/load-data/)一致。 + +--- + +## 1. 暂存区(Stage) +EverDrive 的数据工程团队将每批四个文件——会话、帧事件、检测负载(包含嵌套 JSON 字段)和帧嵌入——导出到 S3 存储桶。本指南使用 Parquet 作为示例格式,但您可以通过调整 `FILE_FORMAT` 子句来使用 CSV、JSON 或其他支持的格式。创建一次命名连接,然后在各个暂存区中重复使用。 + +```sql +CREATE OR REPLACE CONNECTION everdrive_s3 + STORAGE_TYPE = 's3' + ACCESS_KEY_ID = '' + SECRET_ACCESS_KEY = ''; + +CREATE OR REPLACE STAGE drive_stage + URL = 's3://everdrive-lakehouse/raw/' + CONNECTION = (CONNECTION_NAME = 'everdrive_s3') + FILE_FORMAT = (TYPE = 'PARQUET'); +``` + +有关更多选项,请参阅[创建暂存区](/cn/sql/sql-commands/ddl/stage/ddl-create-stage)。 + +列出导出文件夹(本演练中为 Parquet)以确认它们可见: + +```sql +LIST @drive_stage/sessions/; +LIST @drive_stage/frame-events/; +LIST @drive_stage/payloads/; +LIST @drive_stage/embeddings/; +``` + +--- + +## 2. 预览 +在加载任何数据之前,查看 Parquet 文件内部以验证架构和样本记录。 + +```sql +SELECT * +FROM @drive_stage/sessions/session_2024_08_16.parquet +LIMIT 5; + +SELECT * +FROM @drive_stage/frame-events/frame_events_2024_08_16.parquet +LIMIT 5; +``` + +根据需要对负载和嵌入重复预览。Databend 会自动使用暂存区上指定的文件格式。 + +--- + +## 3. COPY INTO +将每个文件加载到本指南中使用的表中。使用内联类型转换将传入列映射到表列;以下投影假定为 Parquet,但相同的结构适用于其他格式。 + +### 会话 +```sql +COPY INTO drive_sessions (session_id, vehicle_id, route_name, start_time, end_time, weather, camera_setup) +FROM ( + SELECT session_id::STRING, + vehicle_id::STRING, + route_name::STRING, + start_time::TIMESTAMP, + end_time::TIMESTAMP, + weather::STRING, + camera_setup::STRING + FROM @drive_stage/sessions/ +) +FILE_FORMAT = (TYPE = 'PARQUET'); +``` + +### 帧事件 +```sql +COPY INTO frame_events (frame_id, session_id, frame_index, captured_at, event_type, risk_score) +FROM ( + SELECT frame_id::STRING, + session_id::STRING, + frame_index::INT, + captured_at::TIMESTAMP, + event_type::STRING, + risk_score::DOUBLE + FROM @drive_stage/frame-events/ +) +FILE_FORMAT = (TYPE = 'PARQUET'); +``` + +### 检测负载 +负载文件包含嵌套列(`payload` 列是一个 JSON 对象)。使用相同的投影将它们复制到 `frame_payloads` 表中。 + +```sql +COPY INTO frame_payloads (frame_id, run_stage, payload, logged_at) +FROM ( + SELECT frame_id::STRING, + run_stage::STRING, + payload, + logged_at::TIMESTAMP + FROM @drive_stage/payloads/ +) +FILE_FORMAT = (TYPE = 'PARQUET'); +``` + +### 帧嵌入 +```sql +COPY INTO frame_embeddings (frame_id, session_id, embedding, model_version, created_at) +FROM ( + SELECT frame_id::STRING, + session_id::STRING, + embedding::VECTOR(4), -- 将 4 替换为您的实际嵌入维度 + model_version::STRING, + created_at::TIMESTAMP + FROM @drive_stage/embeddings/ +) +FILE_FORMAT = (TYPE = 'PARQUET'); +``` + +所有下游指南(分析/搜索/向量/地理)现在都可以看到此批次数据。 + +--- + +## 4. 流(Stream)(可选) +如果您希望下游作业在每次 `COPY INTO` 后对新行做出反应,请在关键表(例如 `frame_events`)上创建流。流的使用遵循[持续数据流水线 → 流](/cn/guides/load-data/continuous-data-pipelines/stream)指南。 + +```sql +CREATE OR REPLACE STREAM frame_events_stream ON TABLE frame_events; + +SELECT * FROM frame_events_stream; -- 显示自上次消费以来的新行 +``` + +处理流后,调用 `CONSUME STREAM frame_events_stream;`(或将行插入另一个表)以推进偏移量。 + +--- + +## 5. 任务(Task)(可选) +任务按计划执行**一条 SQL 语句**。为每个表创建一个小任务(或者如果您更喜欢单个入口点,可以调用存储过程)。 + +```sql +CREATE OR REPLACE TASK task_load_sessions + WAREHOUSE = 'default' + SCHEDULE = 5 MINUTE +AS + COPY INTO drive_sessions (session_id, vehicle_id, route_name, start_time, end_time, weather, camera_setup) + FROM ( + SELECT session_id::STRING, + vehicle_id::STRING, + route_name::STRING, + start_time::TIMESTAMP, + end_time::TIMESTAMP, + weather::STRING, + camera_setup::STRING + FROM @drive_stage/sessions/ + ) + FILE_FORMAT = (TYPE = 'PARQUET'); + +ALTER TASK task_load_sessions RESUME; + +CREATE OR REPLACE TASK task_load_frame_events + WAREHOUSE = 'default' + SCHEDULE = 5 MINUTE +AS + COPY INTO frame_events (frame_id, session_id, frame_index, captured_at, event_type, risk_score) + FROM ( + SELECT frame_id::STRING, + session_id::STRING, + frame_index::INT, + captured_at::TIMESTAMP, + event_type::STRING, + risk_score::DOUBLE + FROM @drive_stage/frame-events/ + ) + FILE_FORMAT = (TYPE = 'PARQUET'); + +ALTER TASK task_load_frame_events RESUME; + +-- 对 frame_payloads 和 frame_embeddings 重复此操作 +``` + +有关 cron 语法、依赖项和错误处理,请参阅[持续数据流水线 → 任务](/cn/guides/load-data/continuous-data-pipelines/task)。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/_category_.json b/docs/cn/guides/54-query/_category_.json index c512ee2022..eceb721ed2 100644 --- a/docs/cn/guides/54-query/_category_.json +++ b/docs/cn/guides/54-query/_category_.json @@ -1,3 +1,3 @@ { - "label": "查询" + "label": "统一工作负载(Unified Workloads)" } \ No newline at end of file diff --git a/docs/cn/guides/54-query/index.md b/docs/cn/guides/54-query/index.md index b1dab4a9cc..4e9a5d7075 100644 --- a/docs/cn/guides/54-query/index.md +++ b/docs/cn/guides/54-query/index.md @@ -1,124 +1,15 @@ --- -title: 在 Databend 中查询数据 +title: 统一工作负载(Unified Workloads) --- -Databend 支持标准 SQL,并带有 ANSI SQL:2003 分析扩展。本指南涵盖从基础到高级的核心查询技术,按学习路径组织,便于高效掌握。 +Databend 现已成为统一引擎,支持 SQL 分析(SQL Analytics)、多模态搜索(Multimodal Search)、向量相似度计算(Vector Similarity)、地理空间分析(Geospatial Analysis)和持续 ETL(Continuous ETL)。本迷你系列教程使用 **EverDrive Smart Vision** 场景(会话 ID 如 `SES-20240801-SEA01`,帧 ID 如 `FRAME-0001`)展示如何让单一数据集流经所有工作负载,无需在系统间复制数据。 -## 学习路径 +| 指南 | 涵盖内容 | +|-------|----------------| +| [SQL 分析](./00-sql-analytics.md) | 构建共享表,切分会话,添加窗口/聚合加速 | +| [JSON 与搜索](./01-json-search.md) | 存储检测负载并 `QUERY` 风险场景 | +| [向量搜索](./02-vector-db.md) | 保存帧嵌入并查找语义邻居 | +| [地理分析](./03-geo-analytics.md) | 使用 `HAVERSINE`、多边形、H3 映射事件 | +| [湖仓 ETL](./04-lakehouse-etl.md) | 暂存文件,`COPY INTO` 表,可选流/任务 | -**📚 SQL 新手?** 从[基础查询](./00-basics/index.md)开始 -**🔗 需要连接数据?** 前往[组合数据](./01-combining-data/index.md) -**⚡ 需要自定义逻辑?** 查看[高级功能](./02-advanced/index.md) -**🚀 遇到性能问题?** 访问[查询优化(Query Optimization)](./03-optimization/index.md) - ---- - -## 📚 [基础查询](./00-basics/index.md) - -掌握数据选择与聚合的基本 SQL 操作。 - -### [筛选与选择](./00-basics/filtering-selection.md) -```sql --- 选择与筛选数据 -SELECT name, salary FROM employees -WHERE department = 'Engineering' -ORDER BY salary DESC; -``` - -### [聚合数据](./00-basics/aggregating-data.md) -```sql --- 分组并汇总数据 -SELECT department, - COUNT(*) as emp_count, - AVG(salary) as avg_salary -FROM employees -GROUP BY department; -``` - -### [高级分组](./00-basics/groupby/index.md) -使用 CUBE、ROLLUP 和 GROUPING SETS 进行多维分析 - ---- - -## 🔗 [组合数据](./01-combining-data/index.md) - -通过 JOIN 和 CTE 连接多源数据。 - -### [JOIN](./01-combining-data/joins.md) -```sql --- 关联相关表 -SELECT e.name, d.department_name -FROM employees e -JOIN departments d ON e.department_id = d.id; -``` - -### [公用表表达式(CTE)](./01-combining-data/cte.md) -```sql --- 构建复杂查询 -WITH high_earners AS ( - SELECT * FROM employees WHERE salary > 75000 -) -SELECT department, COUNT(*) as count -FROM high_earners GROUP BY department; -``` - ---- - -## ⚡ [高级功能](./02-advanced/index.md) - -通过自定义函数与外部集成扩展能力。 - -### [用户自定义函数(User-Defined Functions)](./02-advanced/udf.md) -```sql --- 创建可复用函数 -CREATE FUNCTION calculate_bonus(salary FLOAT, rating FLOAT) -RETURNS FLOAT AS $$ salary * rating * 0.1 $$; -``` - -### 更多高级功能 -- [外部函数(External Functions)](./02-advanced/external-function.md) - 云端机器学习集成 -- [存储过程(Stored Procedures)](./02-advanced/stored-procedure.md) - 多步操作 -- [序列(Sequences)](./02-advanced/sequences.md) - 唯一 ID 生成 - ---- - -## 🚀 [查询优化(Query Optimization)](./03-optimization/index.md) - -利用分析工具诊断并提升查询性能。 - -### [查询画像(Query Profile)](./03-optimization/query-profile.md) -可视化执行计划分析(Databend Cloud:监控 → SQL 历史) - -### [性能分析](./03-optimization/query-hash.md) -```sql --- 分析查询执行 -EXPLAIN SELECT * FROM orders o -JOIN customers c ON o.customer_id = c.id -WHERE o.order_date >= '2023-01-01'; -``` - ---- - -## 快速参考 - -### 最常用模式 -```sql --- Top N 查询 -SELECT * FROM employees ORDER BY salary DESC LIMIT 10; - --- 筛选并聚合 -SELECT department, AVG(salary) -FROM employees -WHERE hire_date >= '2023-01-01' -GROUP BY department -HAVING AVG(salary) > 70000; - --- 使用 CTE 进行连接 -WITH recent_orders AS ( - SELECT * FROM orders WHERE order_date >= '2023-01-01' -) -SELECT c.name, COUNT(*) as order_count -FROM customers c -JOIN recent_orders o ON c.id = o.customer_id -GROUP BY c.name; -``` \ No newline at end of file +按顺序完成这些教程,了解 Databend 的单一优化器(Query Optimizer)如何在同一车队数据上为分析、搜索、向量、地理和加载流水线提供支持。 \ No newline at end of file diff --git a/docs/cn/guides/55-performance/03-fulltext-index.md b/docs/cn/guides/55-performance/03-fulltext-index.md index 55899d699e..083bb0d2fa 100644 --- a/docs/cn/guides/55-performance/03-fulltext-index.md +++ b/docs/cn/guides/55-performance/03-fulltext-index.md @@ -1,32 +1,36 @@ --- -title: 全文索引 +title: 全文索引(Full-Text Index) --- -# 全文索引:实现闪电般快速的自动文本搜索 +:::info +想要实践操作?请参阅 [JSON 与搜索指南](/guides/query/json-search)。 +::: + +# 全文索引(Full-Text Index):自动化的闪电般快速文本搜索 import EEFeature from '@site/src/components/EEFeature'; -全文索引(倒排索引)通过建立词条到文档的映射关系,自动实现海量文档集合的闪电式文本检索,无需执行缓慢的全表扫描。 +全文索引(Full-Text Index,也称倒排索引 Inverted Index)通过将词条映射到文档,自动实现对大型文档集合的闪电般快速文本搜索,无需进行缓慢的全表扫描。 -## 解决哪些问题? +## 解决什么问题? -大规模数据集上的文本搜索面临显著性能挑战: +大型数据集上的文本搜索操作面临显著的性能挑战: -| 问题 | 影响 | 全文索引解决方案 | +| 问题 | 影响 | 全文索引(Full-Text Index)解决方案 | |---------|--------|-------------------------| -| **LIKE 查询缓慢** | `WHERE content LIKE '%keyword%'` 需扫描整表 | 直接词条定位,跳过无关文档 | -| **全表扫描** | 每次文本搜索都需读取所有行 | 仅读取包含搜索词条的文档 | -| **搜索体验差** | 用户需等待数秒/分钟获取结果 | 亚秒级搜索响应时间 | -| **搜索功能有限** | 仅支持基础模式匹配 | 支持高级功能:模糊搜索、相关性评分 | -| **资源消耗高** | 文本搜索过度消耗 CPU/内存 | 索引搜索仅需最少资源 | +| **LIKE 查询缓慢** | `WHERE content LIKE '%keyword%'` 扫描整个表 | 直接词条查找,跳过无关文档 | +| **全表扫描** | 每次文本搜索读取所有行 | 仅读取包含搜索词条的文档 | +| **搜索体验差** | 用户等待数秒/数分钟才能获得搜索结果 | 亚秒级搜索响应时间 | +| **搜索能力有限** | 仅支持基本模式匹配 | 高级功能:模糊搜索、相关性评分 | +| **资源使用率高** | 文本搜索消耗过多 CPU/内存 | 索引搜索所需资源极少 | -**示例**:在 1000 万条日志中搜索 "kubernetes error"。无全文索引时需扫描全部 1000 万行,使用全文索引可直接定位约 1000 个匹配文档,瞬间返回结果。 +**示例**:在 1000 万条日志记录中搜索 "kubernetes error"。没有全文索引时,需要扫描全部 1000 万行。使用全文索引后,可以直接找到约 1000 个匹配文档,瞬间完成。 ## 工作原理 -全文索引创建词条到文档的反向映射: +全文索引(Full-Text Index)创建从词条到文档的倒排映射: | 词条 | 文档 ID | |------|-------------| @@ -34,66 +38,66 @@ import EEFeature from '@site/src/components/EEFeature'; | "error" | 101, 892, 1847 | | "pod" | 205, 1847, 2901 | -搜索 "kubernetes error" 时,索引直接定位同时包含两个词条的文档 (101, 1847),无需扫描整表。 +搜索 "kubernetes error" 时,索引会找到包含这两个词条的文档(101, 1847),无需扫描整个表。 -## 快速配置 +## 快速设置 ```sql --- 创建含文本字段的表 +-- 创建包含文本内容的表 CREATE TABLE logs(id INT, message TEXT, timestamp TIMESTAMP); --- 创建全文索引 - 自动索引新数据 +-- 创建全文索引(Full-Text Index)- 自动索引新数据 CREATE INVERTED INDEX logs_message_idx ON logs(message); --- 仅需对索引创建前已存在的数据执行一次性刷新 +-- 仅对索引创建前的现有数据需要一次性刷新 REFRESH INVERTED INDEX logs_message_idx ON logs; --- 使用 MATCH 函数搜索 - 自动优化执行 +-- 使用 MATCH 函数搜索 - 完全自动优化 SELECT * FROM logs WHERE MATCH(message, 'error kubernetes'); ``` **自动索引管理**: -- **新数据**:插入时自动索引,无需人工干预 -- **存量数据**:仅需对索引创建前存在的数据执行一次性刷新 -- **持续维护**:Databend 自动维护最优搜索性能 +- **新数据**:插入时自动索引 - 无需手动操作 +- **现有数据**:仅对索引创建前存在的数据需要一次性刷新 +- **持续维护**:Databend 自动维护最佳搜索性能 ## 搜索函数 | 函数 | 用途 | 示例 | |----------|---------|---------| -| `MATCH(column, 'terms')` | 基础文本搜索 | `MATCH(content, 'database performance')` | -| `QUERY('column:terms')` | 高级查询语法 | `QUERY('title:"full text" AND content:search')` | +| `MATCH(column, 'terms')` | 基本文本搜索 | `MATCH(content, 'database performance')` | +| `QUERY('column:terms')` | 高级查询(Query)语法 | `QUERY('title:"full text" AND content:search')` | | `SCORE()` | 相关性评分 | `SELECT *, SCORE() FROM docs WHERE MATCH(...)` | ## 高级搜索功能 ### 模糊搜索 ```sql --- 支持容错匹配(fuzziness=1 允许 1 个字符差异) -SELECT * FROM logs WHERE MATCH(message, 'kuberntes', 'fuzziness=1'); +-- 即使有拼写错误也能找到文档(fuzziness=1 允许 1 个字符差异) +SELECT * FROM logs WHERE MATCH(message, 'kubernetes', 'fuzziness=1'); ``` ### 相关性评分 ```sql --- 获取带相关性评分的结果,按阈值过滤 +-- 获取带有相关性评分的结果,按最低分数过滤 SELECT id, message, SCORE() as relevance FROM logs WHERE MATCH(message, 'critical error') AND SCORE() > 0.5 ORDER BY SCORE() DESC; ``` -### 复合查询 +### 复杂查询(Query) ```sql --- 支持布尔运算符的高级查询语法 +-- 使用布尔运算符的高级查询(Query)语法 SELECT * FROM docs WHERE QUERY('title:"user guide" AND content:(tutorial OR example)'); ``` ## 完整示例 -此示例演示在 Kubernetes 日志数据上创建全文索引并执行多样化搜索: +此示例演示了在 Kubernetes 日志数据上创建全文搜索索引(Full-Text Index)并使用各种函数进行搜索: ```sql --- 创建含计算列的表 +-- 创建带有计算列的表 CREATE TABLE k8s_logs ( event_id INT, event_data VARIANT, @@ -101,24 +105,24 @@ CREATE TABLE k8s_logs ( event_message VARCHAR AS (event_data['message']::VARCHAR) STORED ); --- 在 event_message 列创建倒排索引 +-- 在 "event_message" 列上创建倒排索引(Inverted Index) CREATE INVERTED INDEX event_message_fulltext ON k8s_logs(event_message); --- 插入示例数据 +-- 插入综合示例数据 INSERT INTO k8s_logs (event_id, event_data, event_timestamp) VALUES (1, PARSE_JSON('{ "message": "Pod scheduled", "object_type": "Pod", - "name": "frontend-1", + "name": "极速-1", "namespace": "production", "node": "node-01", "status": "Scheduled" }'), '2024-04-08T08:00:00Z'); -INSERT INTO k8s_logs (event_id, event_data, event_timestamp) +INSERT INTO k8s_logs (极速_id, event_data, event_timestamp) VALUES (2, PARSE_JSON('{ @@ -128,13 +132,13 @@ VALUES "namespace": "development", "replicas": 3 }'), - '2024-04-08T09:15:00Z'); + '2024-极速-08T09:15:00Z'); INSERT INTO k8s_logs (event_id, event_data, event_timestamp) VALUES (3, PARSE_JSON('{ - "message": "Node condition changed", +极速 "message": "Node condition changed", "object_type": "Node", "name": "node-02", "condition": "Ready", @@ -165,9 +169,9 @@ VALUES "status": "Bound", "volume": "pv-logs" }'), - '2024-04-08T12:00:00Z'); + '202极速-04-08T12:00:00Z'); --- 基础搜索:查找含 "PersistentVolume" 的事件 +-- 基本搜索包含 "PersistentVolume" 的事件 SELECT event_id, event_message @@ -180,7 +184,7 @@ WHERE event_id: 5 event_message: PersistentVolume claim created --- 使用 EXPLAIN 验证索引使用 +-- 使用 EXPLAIN 验证索引(Index)使用情况 EXPLAIN SELECT event_id, event_message FROM k8s_logs WHERE MATCH(event_message, 'PersistentVolume'); -[ EXPLAIN ]----------------------------------- @@ -193,13 +197,13 @@ Filter ├── output columns: [event_id (#0), event_message (#3), _search_matched (#4)] ├── read rows: 1 ├── read size: < 1 KiB - ├── partitions total: 5 + ├── partitions total: 5极速 ├── partitions scanned: 1 ├── pruning stats: [segments: , blocks: ] ├── push downs: [filters: [k8s_logs._search_matched (#4)], limit: NONE] └── estimated rows: 5.00 --- 带相关性评分的高级搜索 +-- 带有相关性评分的高级搜索 SELECT event_id, event_message, @@ -217,7 +221,7 @@ WHERE event_timestamp: 2024-04-08 12:00:00 score(): 0.86304635 --- 模糊搜索示例(支持拼写容错) +-- 模糊搜索示例(处理拼写错误) SELECT event_id, event_message, event_timestamp FROM @@ -231,49 +235,49 @@ WHERE event_timestamp: 2024-04-08 12:00:00 ``` -**示例核心要点**: -- `inverted pruning: 5 to 1` 表明索引将扫描块数从 5 降至 1 -- 相关性评分实现按匹配质量排序结果 -- 模糊搜索支持拼写差异(如 "create" 与 "created") +**示例要点**: +- `inverted pruning: 5 to 1` 显示索引(Index)将扫描的块从 5 个减少到 1 个 +- 相关性评分有助于按匹配质量对结果进行排序 +- 模糊搜索即使有拼写错误也能找到结果("create" vs "created") ## 最佳实践 -| 实践方案 | 优势 | +| 实践 | 优势 | |----------|---------| -| **为高频搜索列创建索引** | 聚焦搜索查询中的目标列 | -| **使用 MATCH 替代 LIKE** | 充分发挥索引性能优势 | -| **监控索引使用状态** | 通过 EXPLAIN 验证索引生效情况 | -| **考虑多索引方案** | 不同列可建立独立索引 | +| **索引(Index)常用搜索列** | 专注于搜索查询(Query)中使用的列 | +| **使用 MATCH 而非 LIKE** | 利用自动索引(Index)性能 | +| **监控索引(Index)使用情况** | 使用 EXPLAIN 验证索引(Index)利用率 | +| **考虑多个索引(Index)** | 不同列可以有单独的索引(Index) | -## 核心命令 +## 基本命令 -| 命令 | 用途 | 使用场景 | +| 命令 | 用途 | 使用时机 | |---------|---------|-------------| -| `CREATE INVERTED INDEX name ON table(column)` | 新建全文索引 | 初始配置 - 新数据自动索引 | -| `REFRESH INVERTED INDEX name ON table` | 索引存量数据 | 仅需对索引前数据执行一次 | -| `DROP INVERTED INDEX name ON table` | 删除索引 | 不再需要索引时 | +| `CREATE INVERTED INDEX name ON table(column)` | 创建新的全文索引(Full-Text Index) | 初始设置 - 对新数据自动生效 | +| `极速REFRESH INVERTED INDEX name ON table` | 索引(Index)现有数据 | 仅对预先存在的数据一次性使用 | +| `DROP INVERTED INDEX name ON table` | 删除索引(Index) | 不再需要索引(Index)时 | ## 重要说明 :::tip -**适用场景**: -- 海量文本数据集(文档/日志/评论) -- 高频文本搜索操作 -- 需要高级搜索功能(模糊匹配/相关性评分) -- 性能敏感的搜索应用 +**何时使用全文索引(Full-Text Index):** +- 大型文本数据集(文档、日志、评论) +- 频繁的文本搜索操作 +- 需要高级搜索功能(模糊、评分) +- 性能关键的搜索应用 -**非适用场景**: +**何时不使用:** - 小型文本数据集 -- 仅需精确字符串匹配 -- 低频搜索操作 +- 仅精确字符串匹配 +- 不频繁的搜索操作 ::: -## 索引限制 +## 索引(Index)限制 -- 单列仅能归属一个倒排索引 -- 数据插入后需手动刷新(针对索引创建前已存在的数据) -- 需额外存储空间存放索引数据 +- 每列只能在一个倒排索引(Inverted Index)中 +- 需要在数据插入后刷新(如果数据在索引创建前存在) +- 索引(Index)数据使用额外的存储空间 --- -*全文索引是处理海量文档集合并实现高速、复杂文本搜索的关键组件。* \ No newline at end of file +*全文索引(Full-Text Index)对于需要在大型文档集合中进行快速、复杂文本搜索的应用至关重要。* \ No newline at end of file