From 05288d909517561cf2e2c9ca0073f2002cf51f80 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:45:10 +0000 Subject: [PATCH 01/12] [INIT] Start translation to Simplified-Chinese --- .translation-init | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.translation-init b/.translation-init index f513d9c7d1..5b22c20f12 100644 --- a/.translation-init +++ b/.translation-init @@ -1 +1 @@ -Translation initialization: 2025-10-23T05:40:09.780391 +Translation initialization: 2025-10-24T00:45:09.769818 From 99c6c669e5c5a3631de9bd811dda8655ef0f4b5a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:46:56 +0000 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../01-dee/10-enterprise-features.md | 108 +++++++++--------- 1 file changed, 54 insertions(+), 54 deletions(-) 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..f337533503 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) | 查询性能 | 为 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 社区版与企业版对比 + +本节比较了 Databend 社区版与 Databend 企业版在关键能力方面的差异: ### 核心数据库引擎 -### 企业级安全与合规 +### 企业安全与合规 @@ -80,7 +80,7 @@ tbody={[ @@ -106,9 +106,9 @@ tbody={[ -### 企业级存储与备份 +### 企业存储与备份 @@ -148,7 +148,7 @@ tbody={[ -### 企业级支持 +### 企业支持 +/> \ No newline at end of file From 83ca4b936524281b3ec816259332b776f4e18c1f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:47:28 +0000 Subject: [PATCH 03/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../51-ai-functions/01-external-functions.md | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) 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..f6db424dfc 100644 --- a/docs/cn/guides/51-ai-functions/01-external-functions.md +++ b/docs/cn/guides/51-ai-functions/01-external-functions.md @@ -1,31 +1,31 @@ --- -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 的机器上以加快推理速度 | -| **数据隐私** | 将数据保留在您的基础设施内 | -| **可扩展性** | 独立扩展和资源优化 | -| **灵活性** | 支持任何编程语言和 ML 框架 | +| **自定义模型** | 使用任意开源或专有的 AI/ML 模型 | +| **GPU 加速** | 在配备 GPU 的机器上部署,实现更快的推理 | +| **数据隐私** | 数据始终保留在您的基础设施内 | +| **可扩展性** | 支持独立扩展与资源优化 | +| **灵活性** | 兼容任意编程语言和机器学习(ML)框架 | ## 工作原理 -1. **创建 AI 服务器**:使用 Python 和 [databend-udf](https://pypi.org/project/databend-udf) 构建您的 AI/ML 服务器 -2. **注册函数**:使用 `CREATE FUNCTION` 将您的服务器连接到 Databend -3. **在 SQL 中使用**:直接在 SQL 查询中调用您的自定义 AI 函数 +1. **创建 AI 服务器**:使用 Python 和 [databend-udf](https://pypi.org/project/databend-udf) 构建您的 AI/ML 服务器 +2. **注册函数**:通过 `CREATE FUNCTION` 将您的服务器连接到 Databend +3. **在 SQL 中使用**:直接在 SQL 查询(Query)中调用自定义 AI 函数 ## 示例:文本嵌入函数 ```python -# 简单的嵌入 UDF 服务器演示 +# Simple embedding UDF server demo from databend_udf import udf, UDFServer from sentence_transformers import SentenceTransformer @@ -37,19 +37,19 @@ model = SentenceTransformer('all-mpnet-base-v2') # 768 维向量 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 From 9b42773a2b669214f1aaba2d63f19f75e347ae7d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:49:09 +0000 Subject: [PATCH 04/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/00-sql-analytics.md | 277 ++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 docs/cn/guides/54-query/00-sql-analytics.md 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..02308b984d --- /dev/null +++ b/docs/cn/guides/54-query/00-sql-analytics.md @@ -0,0 +1,277 @@ +--- +title: SQL 分析 +--- + +> **场景:** EverDrive Smart Vision 分析师整理了一组共享的驾驶会话和关键帧,使每个下游工作负载都能查询相同的 ID,而无需在系统之间复制数据。 + +本教程构建了一个微型 **EverDrive Smart Vision** 数据集,并展示了 Databend 的单一优化器如何在其余指南中工作。您在此处创建的每个 ID(`SES-20240801-SEA01`、`FRAME-0001` …)都会在 JSON、向量、地理和 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; +``` + +提前过滤可使后续的连接和聚合更快。文档:[WHERE & CASE](/sql/sql-commands/query-syntax/query-select#where-clause)。 + +--- + +## 3. JOIN(连接) +### INNER JOIN ... USING(内连接) +将会话元数据与帧级事件结合。 + +```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 负载中的检测对象结合。 + +```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; +``` + +窗口函数(Window Function)允许您内联表达滚动总计或平均值。完整列表:[窗口函数](/sql/sql-functions/window-functions)。 + +--- + +## 6. 聚合索引加速 +使用[聚合索引(Aggregating Index)](/guides/performance/aggregating-index)缓存繁重的汇总,使仪表盘(Dashboard)保持快速响应。 + +```sql +CREATE OR REPLACE AGGREGATING INDEX idx_route_event_summary ON frame_events +AS +SELECT session_id, + event_type, + COUNT(*) AS event_count, + AVG(risk_score) AS avg_risk +FROM frame_events +GROUP BY session_id, event_type; +``` + +现在运行与之前相同的汇总查询(Query)——优化器将自动从索引中提取结果: + +```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` 节点而不是全表扫描。Databend 会在新帧到达时保持索引(Index)的新鲜度,无需额外的 ETL 作业即可提供亚秒级仪表盘。 + +--- + +## 7. 存储过程自动化 +您还可以将报告逻辑包装在存储过程中,以便在计划作业期间按预期方式运行。 + +```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 任务或自动警报中使用返回的结果集。了解更多:[存储过程脚本](/sql/stored-procedure-scripting)。 + +--- + +您现在拥有一个完整的循环:摄取会话数据、过滤、连接、聚合、加速繁重查询、随时间趋势分析并发布。交换过滤器或连接以将相同的方法应用于其他智能驾驶 KPI,如驾驶员评分、传感器退化或算法比较。 \ No newline at end of file From a5208ba6d96f02116702595ef71e3537b524185e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:50:17 +0000 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/01-json-search.md | 140 ++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 docs/cn/guides/54-query/01-json-search.md 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..51686b3401 --- /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`)。更多提示:[半结构化数据](/guides/load-data/load-semistructured/load-ndjson)。 + +--- + +## 3. 类 Elasticsearch 搜索 +`QUERY` 使用 Elasticsearch/Lucene 语法,因此您可以组合布尔逻辑、范围、权重提升(Boosting)和列表。以下是在 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; +``` + +查看[搜索函数](/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 From 481e7fcdd1023a3e76ac3f0d80621d1dd9980df4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:50:52 +0000 Subject: [PATCH 06/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/02-vector-db.md | 100 ++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 docs/cn/guides/54-query/02-vector-db.md 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..14ee68a8f4 --- /dev/null +++ b/docs/cn/guides/54-query/02-vector-db.md @@ -0,0 +1,100 @@ +--- +title: 向量搜索(Vector Search) +--- + +> **场景:** EverDrive Smart Vision 为风险帧附加紧凑的视觉嵌入向量(Vision Embedding),以便调查团队可以直接在 Databend 中检索相似情况。 + +每个提取的帧都有一个视觉嵌入向量(Vision Embedding),以便感知工程师(Perception Engineer)可以发现相似场景。本指南展示如何插入这些向量并在相同的 EverDrive ID 上执行语义搜索(Semantic Search)。 + +## 1. 创建示例表 +我们使用四维向量存储一个紧凑示例以提高可读性。在生产环境中,您可能会保留来自 CLIP 或自监督模型(Self-supervised Model)的 512 维或 1536 维嵌入向量(Embedding)。 + +```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; +``` + +余弦距离(Cosine Distance)计算使用我们之前创建的 HNSW 索引(Index),首先返回最接近的帧。 + +--- + +## 3. WHERE 过滤 + 相似度 +将相似度搜索与传统谓词(Predicate)结合以缩小结果范围。 + +```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)语义 + 风险元数据 +将语义结果连接回风险评分(Risk Score)或检测负载(Detection Payload),以进行更丰富的调查。 + +```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; +``` + +这个混合视图(Hybrid View)呈现“看起来像 FRAME-0001 并且也触发了高风险事件的帧”。 \ No newline at end of file From b51924c09ce24f5b2e4e568c01c78f24d6eed196 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:52:04 +0000 Subject: [PATCH 07/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/03-geo-analytics.md | 139 ++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 docs/cn/guides/54-query/03-geo-analytics.md 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..2882617949 --- /dev/null +++ b/docs/cn/guides/54-query/03-geo-analytics.md @@ -0,0 +1,139 @@ +--- +title: 地理分析(Geo Analytics) +--- + +> **场景:** EverDrive Smart Vision 为每个关键帧记录 GPS 坐标,以便运营团队能够在城市范围内绘制危险驾驶热点区域。 + +每一帧都标记了 GPS 坐标,因此我们可以在城市范围内绘制危险情况的分布图。本指南添加了一个地理空间(Geospatial)表,并使用相同的 EverDrive 会话 ID 演示空间过滤器、多边形(Polygon)和 H3 分桶(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.1, 210); +``` + +文档:[地理空间数据类型](https://docs.databend.cn/sql/sql-reference/data-types/geospatial)。 + +--- + +## 2. ST_DISTANCE 半径过滤 +`ST_DISTANCE` 函数测量几何图形之间的距离。将帧位置和热点都转换为 Web 墨卡托投影(Web Mercator,SRID 3857),使结果以米为单位表示,然后过滤到 500 米范围内。 + +```sql +SELECT g.frame_id, + g.session_id, + e.event_type, + e.risk_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_DISTANCE( + 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)`。更喜欢直接的大圆距离(Great-circle Distance)计算?换用 `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, + -122.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 热力图 +按六边形单元(Hexagonal Cell)聚合事件以构建路线热力图。 + +```sql +SELECT GEO_TO_H3(ST_X(location), ST_Y(location), 8) AS h3_cell, + COUNT(*) AS frame_count, + AVG(e.risk_score) AS avg_risk +FROM drive_geo +JOIN frame_events e USING (frame_id) +GROUP BY h3_cell +ORDER BY avg_risk DESC; +``` + +文档:[H3 函数](https://docs.databend.cn/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.risk_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. 创建热力图视图(View) +将六边形级别的摘要导出到可视化工具或地图图层。 + +```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.risk_score) AS avg_risk + FROM drive_geo + JOIN frame_events e USING (frame_id) + GROUP BY h3_cell +); +``` + +下游系统可以直接查询(Query)`v_route_heatmap` 以在地图上渲染风险热点,而无需重新处理原始遥测数据。 \ No newline at end of file From 3462cd125b7dd6638fb41e5a56f7dcc1d3d5ce98 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:55:40 +0000 Subject: [PATCH 08/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/04-lakehouse-etl.md | 195 ++++++++++++++++++++ 1 file changed, 195 insertions(+) create mode 100644 docs/cn/guides/54-query/04-lakehouse-etl.md 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..3bbbc7d5d7 --- /dev/null +++ b/docs/cn/guides/54-query/04-lakehouse-etl.md @@ -0,0 +1,195 @@ +--- +title: 湖仓 ETL +--- + +> **场景:** EverDrive Smart Vision 的数据工程团队将每批道路测试数据导出为 Parquet 文件,以便统一工作负载可以在 Databend 中加载、查询和丰富相同的遥测数据。 + +EverDrive 的数据摄取流程非常简单: + +``` +对象存储导出(例如 Parquet) → Stage → COPY INTO → (可选)Stream 与 Task +``` + +调整存储桶路径/凭证(如果格式不同,将 Parquet 替换为实际格式),然后粘贴以下命令。所有语法均遵循官方 [加载数据指南](https://docs.databend.cn/guides/load-data/)。 + +--- + +## 1. Stage + +EverDrive 的数据工程团队每批导出四个文件——会话(sessions)、帧事件(frame events)、检测负载(detection payloads,包含嵌套 JSON 字段)和帧嵌入(frame embeddings)——到 S3 存储桶。本指南以 Parquet 为例,但您可通过调整 `FILE_FORMAT` 子句,灵活使用 CSV、JSON 或其他支持的格式。只需创建一次命名连接(Connection),即可在多个 Stage 中复用。 + +```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'); +``` + +更多选项请参阅 [Create Stage](https://docs.databend.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 文件内容,验证其 Schema 与样本记录。 + +```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; +``` + +如有需要,可对 payloads 和 embeddings 重复上述预览操作。Databend 会自动使用 Stage 上指定的文件格式。 + +--- + +## 3. COPY INTO + +将各文件加载至指南中使用的对应表中。通过内联类型转换(inline casts)将源列映射到目标表列;以下投影以 Parquet 为例,但相同结构也适用于其他格式。 + +### 会话(Sessions) + +```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'); +``` + +### 帧事件(Frame Events) + +```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'); +``` + +### 检测负载(Detection Payloads) + +负载文件包含嵌套列(`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'); +``` + +### 帧嵌入(Frame Embeddings) + +```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`)上创建 Stream。Stream 的使用方式详见 [Continuous Pipeline → Streams](https://docs.databend.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; -- 显示自上次消费后新增的行 +``` + +处理完 Stream 后,请调用 `CONSUME STREAM frame_events_stream;`(或将数据插入其他表),以推进消费偏移量。 + +--- + +## 5. Task(可选) + +Task 可按计划执行**单条 SQL 语句**。建议为每个表创建独立 Task(也可通过存储过程统一调度)。 + +```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 表达式、任务依赖与错误处理,请参阅 [Continuous Pipeline → Tasks](https://docs.databend.cn/guides/load-data/continuous-data-pipelines/task)。 \ No newline at end of file From 9047f5b53f7200703cf437e86093ce900b822617 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:55:45 +0000 Subject: [PATCH 09/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/_category_.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 68fde03393a09e1108668b070bdb061ba8bbf4fc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:56:03 +0000 Subject: [PATCH 10/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/cn/guides/54-query/index.md | 129 +++---------------------------- 1 file changed, 10 insertions(+), 119 deletions(-) diff --git a/docs/cn/guides/54-query/index.md b/docs/cn/guides/54-query/index.md index b1dab4a9cc..26e98a79d4 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) | 保存帧嵌入(frame embeddings)并查找语义邻居 | +| [地理分析](./03-geo-analytics.md) | 使用 `HAVERSINE`、多边形、H3 映射事件 | +| [湖仓 ETL](./04-lakehouse-etl.md) | 暂存文件,`COPY INTO` 表,可选流(stream)/任务(task) | -**📚 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 From 583f4a55ec3b3ee097458b7c71942508df2422b7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:58:19 +0000 Subject: [PATCH 11/12] =?UTF-8?q?=F0=9F=8C=90=20Translate=2010-enterprise-?= =?UTF-8?q?features.md=20to=20Simplified-Chinese?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../55-performance/03-fulltext-index.md | 124 +++++++++--------- 1 file changed, 64 insertions(+), 60 deletions(-) diff --git a/docs/cn/guides/55-performance/03-fulltext-index.md b/docs/cn/guides/55-performance/03-fulltext-index.md index 55899d699e..713841376d 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 个匹配文档。 ## 工作原理 -全文索引创建词条到文档的反向映射: +全文索引创建从词条到文档的倒排映射: | 词条 | 文档 ID | |------|-------------| @@ -34,34 +38,34 @@ 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); -- 创建全文索引 - 自动索引新数据 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')` | +| `MATCH(column, 'terms')` | 基本文本搜索 | `MATCH(content, 'database performance')` | | `QUERY('column:terms')` | 高级查询语法 | `QUERY('title:"full text" AND content:search')` | | `SCORE()` | 相关性评分 | `SELECT *, SCORE() FROM docs WHERE MATCH(...)` | @@ -69,31 +73,31 @@ SELECT * FROM logs WHERE MATCH(message, 'error kubernetes'); ### 模糊搜索 ```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; ``` -### 复合查询 +### 复杂查询 ```sql --- 支持布尔运算符的高级查询语法 +-- 使用布尔运算符的高级查询语法 SELECT * FROM docs WHERE QUERY('title:"user guide" AND content:(tutorial OR example)'); ``` ## 完整示例 -此示例演示在 Kubernetes 日志数据上创建全文索引并执行多样化搜索: +此示例演示了在 Kubernetes 日志数据上创建全文搜索索引并使用各种函数进行搜索: ```sql --- 创建含计算列的表 +-- 创建带有计算列的表 CREATE TABLE k8s_logs ( event_id INT, event_data VARIANT, @@ -101,10 +105,10 @@ 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, @@ -167,7 +171,7 @@ VALUES }'), '2024-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 验证索引使用情况 EXPLAIN SELECT event_id, event_message FROM k8s_logs WHERE MATCH(event_message, 'PersistentVolume'); -[ EXPLAIN ]----------------------------------- @@ -199,7 +203,7 @@ Filter ├── 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` 显示索引将扫描的块从 5 个减少到 1 个 +- 相关性评分有助于按匹配质量对结果进行排序 +- 模糊搜索即使有拼写错误也能找到结果("create" vs "created") ## 最佳实践 -| 实践方案 | 优势 | +| 实践 | 优势 | |----------|---------| -| **为高频搜索列创建索引** | 聚焦搜索查询中的目标列 | -| **使用 MATCH 替代 LIKE** | 充分发挥索引性能优势 | -| **监控索引使用状态** | 通过 EXPLAIN 验证索引生效情况 | -| **考虑多索引方案** | 不同列可建立独立索引 | +| **索引频繁搜索的列** | 专注于搜索查询中使用的列 | +| **使用 MATCH 而非 LIKE** | 利用自动索引性能 | +| **监控索引使用情况** | 使用 EXPLAIN 验证索引利用率 | +| **考虑多个索引** | 不同列可以有单独的索引 | -## 核心命令 +## 基本命令 -| 命令 | 用途 | 使用场景 | +| 命令 | 用途 | 何时使用 | |---------|---------|-------------| -| `CREATE INVERTED INDEX name ON table(column)` | 新建全文索引 | 初始配置 - 新数据自动索引 | -| `REFRESH INVERTED INDEX name ON table` | 索引存量数据 | 仅需对索引前数据执行一次 | +| `CREATE INVERTED INDEX name ON table(column)` | 创建新的全文索引(Full-Text Index) | 初始设置 - 对新数据自动生效 | +| `REFRESH INVERTED INDEX name ON table` | 索引现有数据 | 仅对预先存在的数据一次性使用 | | `DROP INVERTED INDEX name ON table` | 删除索引 | 不再需要索引时 | ## 重要说明 :::tip -**适用场景**: -- 海量文本数据集(文档/日志/评论) -- 高频文本搜索操作 -- 需要高级搜索功能(模糊匹配/相关性评分) -- 性能敏感的搜索应用 +**何时使用全文索引(Full-Text Index):** +- 大型文本数据集(文档、日志、评论) +- 频繁的文本搜索操作 +- 需要高级搜索功能(模糊、评分) +- 性能关键的搜索应用 -**非适用场景**: +**何时不使用:** - 小型文本数据集 -- 仅需精确字符串匹配 -- 低频搜索操作 +- 仅精确字符串匹配 +- 不频繁的搜索操作 ::: ## 索引限制 -- 单列仅能归属一个倒排索引 -- 数据插入后需手动刷新(针对索引创建前已存在的数据) -- 需额外存储空间存放索引数据 +- 每列只能在一个倒排索引 (Inverted Index) 中 +- 需要在数据插入后刷新(如果数据在索引创建前存在) +- 索引数据使用额外的存储空间 --- -*全文索引是处理海量文档集合并实现高速、复杂文本搜索的关键组件。* \ No newline at end of file +*全文索引(Full-Text Index)对于需要在大型文档集合中进行快速、复杂文本搜索的应用至关重要。* \ No newline at end of file From 50e9b795ea7fbdceaef2909b637f7e9c229dddd9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 24 Oct 2025 00:58:23 +0000 Subject: [PATCH 12/12] chore: finalize translation for PR #2897 --- .translation-init | 1 - .../guides/54-query/00-basics/_category_.json | 4 - .../54-query/00-basics/aggregating-data.md | 90 ------- .../54-query/00-basics/filtering-selection.md | 103 -------- .../00-basics/groupby/_category_.json | 3 - .../00-basics/groupby/group-by-cube.md | 77 ------ .../groupby/group-by-grouping-sets.md | 130 ---------- .../00-basics/groupby/group-by-rollup.md | 73 ------ .../54-query/00-basics/groupby/index.md | 157 ------------ docs/cn/guides/54-query/00-basics/index.md | 63 ----- .../01-combining-data/_category_.json | 4 - .../guides/54-query/01-combining-data/cte.md | 94 -------- .../54-query/01-combining-data/index.md | 98 -------- .../54-query/01-combining-data/joins.md | 200 ---------------- .../54-query/01-combining-data/subqueries.md | 157 ------------ .../54-query/02-advanced/_category_.json | 4 - .../54-query/02-advanced/external-function.md | 224 ------------------ docs/cn/guides/54-query/02-advanced/index.md | 59 ----- .../guides/54-query/02-advanced/sequences.md | 134 ----------- .../54-query/02-advanced/stored-procedure.md | 64 ----- docs/cn/guides/54-query/02-advanced/udf.md | 123 ---------- .../54-query/03-optimization/_category_.json | 4 - .../guides/54-query/03-optimization/index.md | 201 ---------------- .../54-query/03-optimization/query-hash.md | 112 --------- .../54-query/03-optimization/query-profile.md | 64 ----- 25 files changed, 2243 deletions(-) delete mode 100644 .translation-init delete mode 100644 docs/cn/guides/54-query/00-basics/_category_.json delete mode 100644 docs/cn/guides/54-query/00-basics/aggregating-data.md delete mode 100644 docs/cn/guides/54-query/00-basics/filtering-selection.md delete mode 100644 docs/cn/guides/54-query/00-basics/groupby/_category_.json delete mode 100644 docs/cn/guides/54-query/00-basics/groupby/group-by-cube.md delete mode 100644 docs/cn/guides/54-query/00-basics/groupby/group-by-grouping-sets.md delete mode 100644 docs/cn/guides/54-query/00-basics/groupby/group-by-rollup.md delete mode 100644 docs/cn/guides/54-query/00-basics/groupby/index.md delete mode 100644 docs/cn/guides/54-query/00-basics/index.md delete mode 100644 docs/cn/guides/54-query/01-combining-data/_category_.json delete mode 100644 docs/cn/guides/54-query/01-combining-data/cte.md delete mode 100644 docs/cn/guides/54-query/01-combining-data/index.md delete mode 100644 docs/cn/guides/54-query/01-combining-data/joins.md delete mode 100644 docs/cn/guides/54-query/01-combining-data/subqueries.md delete mode 100644 docs/cn/guides/54-query/02-advanced/_category_.json delete mode 100644 docs/cn/guides/54-query/02-advanced/external-function.md delete mode 100644 docs/cn/guides/54-query/02-advanced/index.md delete mode 100644 docs/cn/guides/54-query/02-advanced/sequences.md delete mode 100644 docs/cn/guides/54-query/02-advanced/stored-procedure.md delete mode 100644 docs/cn/guides/54-query/02-advanced/udf.md delete mode 100644 docs/cn/guides/54-query/03-optimization/_category_.json delete mode 100644 docs/cn/guides/54-query/03-optimization/index.md delete mode 100644 docs/cn/guides/54-query/03-optimization/query-hash.md delete mode 100644 docs/cn/guides/54-query/03-optimization/query-profile.md diff --git a/.translation-init b/.translation-init deleted file mode 100644 index 5b22c20f12..0000000000 --- a/.translation-init +++ /dev/null @@ -1 +0,0 @@ -Translation initialization: 2025-10-24T00:45:09.769818 diff --git a/docs/cn/guides/54-query/00-basics/_category_.json b/docs/cn/guides/54-query/00-basics/_category_.json deleted file mode 100644 index ca7ee06d50..0000000000 --- a/docs/cn/guides/54-query/00-basics/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "基础查询(Basic Queries)", - "position": 1 -} \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/aggregating-data.md b/docs/cn/guides/54-query/00-basics/aggregating-data.md deleted file mode 100644 index 77c6cd7527..0000000000 --- a/docs/cn/guides/54-query/00-basics/aggregating-data.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: 聚合数据 ---- - -学习如何使用 GROUP BY、聚合函数(Aggregate Function)和高级分组技术来汇总和分析数据。 - -## 基本聚合 - -### 常用聚合函数 -```sql --- 计算行数 -SELECT COUNT(*) FROM employees; - --- 统计函数 -SELECT - AVG(salary) as avg_salary, - MIN(salary) as min_salary, - MAX(salary) as max_salary, - SUM(salary) as total_salary -FROM employees; -``` - -## GROUP BY 基础 - -### 单列分组 -```sql --- 按部门统计员工人数 -SELECT department, COUNT(*) as emp_count -FROM employees -GROUP BY department; - --- 按部门计算平均薪资 -SELECT department, AVG(salary) as avg_salary -FROM employees -GROUP BY department -ORDER BY avg_salary DESC; -``` - -### 多列分组 -```sql --- 按部门和入职年份分组 -SELECT - department, - EXTRACT(YEAR FROM hire_date) as hire_year, - COUNT(*) as count, - AVG(salary) as avg_salary -FROM employees -GROUP BY department, EXTRACT(YEAR FROM hire_date) -ORDER BY department, hire_year; -``` - -### GROUP BY 与 HAVING -```sql --- 查找员工人数超过 5 人的部门 -SELECT department, COUNT(*) as emp_count -FROM employees -GROUP BY department -HAVING COUNT(*) > 5; - --- 平均薪资大于 70000 的部门 -SELECT department, AVG(salary) as avg_salary -FROM employees -GROUP BY department -HAVING AVG(salary) > 70000; -``` - -## 高级分组 - -### GROUP BY ALL -```sql --- 自动按所有非聚合列进行分组 -SELECT department, job_title, COUNT(*) as count -FROM employees -GROUP BY ALL; -``` - -## 高级分组扩展 - -Databend 支持 SQL:2003 标准分组扩展: - -- **[ROLLUP](./groupby/group-by-rollup.md)** - 分层小计 -- **[CUBE](./groupby/group-by-cube.md)** - 所有可能的组合 -- **[GROUPING SETS](./groupby/group-by-grouping-sets.md)** - 自定义组合 - -## 最佳实践 - -1. **使用适当的聚合函数** - COUNT(*) 与 COUNT(column) -2. **分组前过滤** - 在 GROUP BY 前使用 WHERE -3. **使用 HAVING 进行聚合条件过滤** - 在聚合后过滤分组 -4. **考虑索引(Index)** - GROUP BY 的列应当被索引 \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/filtering-selection.md b/docs/cn/guides/54-query/00-basics/filtering-selection.md deleted file mode 100644 index feb82c5e56..0000000000 --- a/docs/cn/guides/54-query/00-basics/filtering-selection.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: 过滤与选择 ---- - -学习在 Databend 中使用 SELECT、WHERE 和基本操作查询(Query)数据的基础知识。 - -## 基本 SELECT 查询 - -### 选择列 -```sql --- 选择特定列 -SELECT name, salary FROM employees; - --- 选择所有列 -SELECT * FROM employees; - --- 使用列别名进行选择 -SELECT name AS employee_name, salary AS monthly_pay -FROM employees; -``` - -### 使用 WHERE 进行过滤 -```sql --- 简单条件 -SELECT * FROM employees WHERE department = 'Engineering'; - --- 多重条件 -SELECT * FROM employees -WHERE salary > 70000 AND department = 'Engineering'; - --- 使用 OR -SELECT * FROM employees -WHERE department = 'Engineering' OR department = 'Marketing'; - --- 范围条件 -SELECT * FROM employees -WHERE salary BETWEEN 60000 AND 80000; - --- 模式匹配 -SELECT * FROM employees -WHERE name LIKE 'A%'; -- 名字以 'A' 开头 -``` - -## 排序结果 - -### ORDER BY 子句 -```sql --- 按单列排序 -SELECT * FROM employees ORDER BY salary DESC; - --- 按多列排序 -SELECT * FROM employees -ORDER BY department ASC, salary DESC; - --- 按列位置排序 -SELECT name, salary FROM employees ORDER BY 2 DESC; -``` - -## 限制结果 - -### LIMIT 和 OFFSET -```sql --- 获取薪水最高的 5 名员工 -SELECT * FROM employees -ORDER BY salary DESC -LIMIT 5; - --- 分页 - 跳过前 10 条,获取接下来的 5 条 -SELECT * FROM employees -ORDER BY salary DESC -LIMIT 5 OFFSET 10; -``` - -## 常用运算符 - -### 比较运算符 -- `=` 等于 -- `!=` 或 `<>` 不等于 -- `>` 大于 -- `<` 小于 -- `>=` 大于或等于 -- `<=` 小于或等于 - -### 逻辑运算符 -- `AND` 两个条件都必须为真 -- `OR` 任一条件为真即可 -- `NOT` 对条件取反 - -### NULL 处理 -```sql --- 检查 NULL 值 -SELECT * FROM employees WHERE manager_id IS NULL; - --- 检查非 NULL 值 -SELECT * FROM employees WHERE manager_id IS NOT NULL; -``` - -## 最佳实践 - -1. **明确指定列** - 在生产环境中避免使用 `SELECT *` -2. **使用索引(Index)** - 对索引列使用 WHERE 条件可以加快查询速度 -3. **限制大量结果** - 在进行探索性查询时,始终使用 LIMIT -4. **尽早过滤** - 尽可能在进行连接(JOIN)之前应用 WHERE 条件 \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/groupby/_category_.json b/docs/cn/guides/54-query/00-basics/groupby/_category_.json deleted file mode 100644 index 354456f0db..0000000000 --- a/docs/cn/guides/54-query/00-basics/groupby/_category_.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "label": "分组(GROUP BY)" -} \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/groupby/group-by-cube.md b/docs/cn/guides/54-query/00-basics/groupby/group-by-cube.md deleted file mode 100644 index 913a332b39..0000000000 --- a/docs/cn/guides/54-query/00-basics/groupby/group-by-cube.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: GROUP BY CUBE ---- - -`GROUP BY CUBE` 是 [GROUP BY](index.md) 子句的扩展,与 [GROUP BY ROLLUP](group-by-rollup.md) 类似。除了生成 `GROUP BY ROLLUP` 的所有行之外,`GROUP BY CUBE` 还会添加所有“交叉表”行。小计行是进一步聚合的行,其值通过计算用于生成分组行的相同聚合函数得出。 - -一个 `CUBE` 分组等价于一连串的 GROUPING SETS(分组集),本质上是一种更简洁的写法。CUBE 规范中的 N 个元素对应 `2^N` 个 `GROUPING SETS`。 - -## 语法 - -```sql -SELECT ... -FROM ... -[ ... ] -GROUP BY CUBE ( groupCube [ , groupCube [ , ... ] ] ) -[ ... ] -``` - -其中: -```sql -groupCube ::= { | | } -``` - -- ``:查询块 SELECT 列表中出现的列别名。 - -- ``:SELECT 列表中表达式的位置。 - -- ``:当前作用域内表的任意表达式。 - - -## 示例 - -假设我们有一张名为 sales_data 的表,其结构及示例数据如下: - -```sql -CREATE TABLE sales_data ( - region VARCHAR(255), - product VARCHAR(255), - sales_amount INT -); - -INSERT INTO sales_data (region, product, sales_amount) VALUES - ('North', 'WidgetA', 200), - ('North', 'WidgetB', 300), - ('South', 'WidgetA', 400), - ('South', 'WidgetB', 100), - ('West', 'WidgetA', 300), - ('West', 'WidgetB', 200); -``` - -现在,我们使用 `GROUP BY CUBE` 子句获取每个地区与产品的总销售额,以及所有可能的聚合结果: - -```sql -SELECT region, product, SUM(sales_amount) AS total_sales -FROM sales_data -GROUP BY CUBE (region, product); -``` - -结果如下: -```sql -+--------+---------+-------------+ -| region | product | total_sales | -+--------+---------+-------------+ -| South | NULL | 500 | -| NULL | WidgetB | 600 | -| West | NULL | 500 | -| North | NULL | 500 | -| West | WidgetB | 200 | -| NULL | NULL | 1500 | -| North | WidgetB | 300 | -| South | WidgetA | 400 | -| North | WidgetA | 200 | -| NULL | WidgetA | 900 | -| West | WidgetA | 300 | -| South | WidgetB | 100 | -+--------+---------+-------------+ -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/groupby/group-by-grouping-sets.md b/docs/cn/guides/54-query/00-basics/groupby/group-by-grouping-sets.md deleted file mode 100644 index d35623a5e7..0000000000 --- a/docs/cn/guides/54-query/00-basics/groupby/group-by-grouping-sets.md +++ /dev/null @@ -1,130 +0,0 @@ ---- -title: GROUP BY GROUPING SETS ---- - -`GROUP BY GROUPING SETS` 是 [GROUP BY](index.md) 子句的强大扩展,可在一条语句中完成多个分组计算。分组集(Grouping Set)是一组维度列。 - -`GROUP BY GROUPING SETS` 等价于在同一结果集中对两个或多个 GROUP BY 操作取 UNION: - -- `GROUP BY GROUPING SETS((a))` 等价于单个分组集操作 `GROUP BY a`。 -- `GROUP BY GROUPING SETS((a),(b))` 等价于 `GROUP BY a UNION ALL GROUP BY b`。 - -## 语法 - -```sql -SELECT ... -FROM ... -[ ... ] -GROUP BY GROUPING SETS ( groupSet [ , groupSet [ , ... ] ] ) -[ ... ] -``` - -其中: -```sql -groupSet ::= { | | } -``` - -- ``:查询块 SELECT 列表中出现的列别名。 -- ``:SELECT 列表中表达式的位置。 -- ``:当前作用域内针对表的任意表达式。 - -## 示例 - -示例数据准备: -```sql --- 创建示例销售表 -CREATE TABLE sales ( - id INT, - sale_date DATE, - product_id INT, - store_id INT, - quantity INT -); - --- 向销售表插入示例数据 -INSERT INTO sales (id, sale_date, product_id, store_id, quantity) -VALUES (1, '2021-01-01', 101, 1, 5), - (2, '2021-01-01', 102, 1, 10), - (3, '2021-01-01', 101, 2, 15), - (4, '2021-01-02', 102, 1, 8), - (5, '2021-01-02', 101, 2, 12), - (6, '2021-01-02', 103, 2, 20); -``` - -### 使用列别名的 GROUP BY GROUPING SETS - -```sql -SELECT product_id AS pid, - store_id AS sid, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY GROUPING SETS((pid), (sid)); -``` - -该查询等价于: - -```sql -SELECT product_id AS pid, - NULL AS sid, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY pid -UNION ALL -SELECT NULL AS pid, - store_id AS sid, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY sid; -``` - -输出: -```sql -+------+------+----------------+ -| pid | sid | total_quantity | -+------+------+----------------+ -| 102 | NULL | 18 | -| NULL | 2 | 47 | -| 101 | NULL | 32 | -| 103 | NULL | 20 | -| NULL | 1 | 23 | -+------+------+----------------+ -``` - -### 使用位置的 GROUP BY GROUPING SETS - -```sql -SELECT product_id, - store_id, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY GROUPING SETS((1), (2)); -``` - -该查询等价于: - -```sql -SELECT product_id, - NULL AS store_id, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY product_id -UNION ALL -SELECT NULL AS product_id, - store_id, - SUM(quantity) AS total_quantity -FROM sales -GROUP BY store_id; -``` - -输出: -```sql -+------------+----------+----------------+ -| product_id | store_id | total_quantity | -+------------+----------+----------------+ -| 102 | NULL | 18 | -| NULL | 2 | 47 | -| 101 | NULL | 32 | -| 103 | NULL | 20 | -| NULL | 1 | 23 | -+------------+----------+----------------+ -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/groupby/group-by-rollup.md b/docs/cn/guides/54-query/00-basics/groupby/group-by-rollup.md deleted file mode 100644 index cac0eb9abd..0000000000 --- a/docs/cn/guides/54-query/00-basics/groupby/group-by-rollup.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: GROUP BY ROLLUP ---- - -`GROUP BY ROLLUP` 是 [GROUP BY](index.md) 子句的扩展,它在分组行之外额外生成小计行。小计行通过再次聚合得到,其值由用于生成分组行的相同聚合函数计算得出。 - -## 语法 - -```sql -SELECT ... -FROM ... -[ ... ] -GROUP BY ROLLUP ( groupRollup [ , groupRollup [ , ... ] ] ) -[ ... ] -``` - -其中: -```sql -groupRollup ::= { | | } -``` - -- ``:查询块 SELECT 列表中出现的列别名。 - -- ``:SELECT 列表中表达式的位置。 - -- ``:当前作用域内表的任意表达式。 - - -## 示例 - -首先创建一个名为 sales_data 的示例表并插入数据: -```sql -CREATE TABLE sales_data ( - region VARCHAR(255), - product VARCHAR(255), - sales_amount INT -); - -INSERT INTO sales_data (region, product, sales_amount) VALUES - ('North', 'WidgetA', 200), - ('North', 'WidgetB', 300), - ('South', 'WidgetA', 400), - ('South', 'WidgetB', 100), - ('West', 'WidgetA', 300), - ('West', 'WidgetB', 200); -``` - -接下来,使用 GROUP BY ROLLUP 子句获取每个区域和产品的销售额,以及每个区域的小计: -```sql -SELECT region, product, SUM(sales_amount) AS total_sales -FROM sales_data -GROUP BY ROLLUP (region, product); -``` - -结果如下: -```sql -+--------+---------+-------------+ -| region | product | total_sales | -+--------+---------+-------------+ -| South | NULL | 500 | -| West | NULL | 500 | -| North | NULL | 500 | -| West | WidgetB | 200 | -| NULL | NULL | 1500 | -| North | WidgetB | 300 | -| South | WidgetA | 400 | -| North | WidgetA | 200 | -| West | WidgetA | 300 | -| South | WidgetB | 100 | -+--------+---------+-------------+ -``` - -在此示例中,GROUP BY ROLLUP 子句计算了每个区域-产品组合、每个区域以及总计的销售额。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/groupby/index.md b/docs/cn/guides/54-query/00-basics/groupby/index.md deleted file mode 100644 index 2ecb20bf4b..0000000000 --- a/docs/cn/guides/54-query/00-basics/groupby/index.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: GROUP BY ---- -import FunctionDescription from '@site/src/components/FunctionDescription'; - - - -`GROUP BY` 子句允许您根据相同的分组项表达式对行进行分组,然后对每个结果组应用聚合函数。分组项表达式可以包括列名或别名、`SELECT` 列表中位置的数字引用、通用表达式或 `SELECT` 列表中的所有非聚合项。 - -Databend 中的 `GROUP BY` 子句附带以下扩展,以实现更全面的数据分组和灵活的数据分析: - -- [GROUP BY CUBE](group-by-cube.md) -- [GROUP BY GROUPING SETS](group-by-grouping-sets.md) -- [GROUP BY ROLLUP](group-by-rollup.md) - -## 语法 - -```sql -SELECT ... - FROM ... - [ ... ] -GROUP BY [ ALL | groupItem [ , groupItem [ , ... ] ] ] - [ ... ] -``` - -其中: - -- **ALL**:当使用关键字 "ALL" 时,Databend 会根据 `SELECT` 列表中的所有非聚合项对数据进行分组。 -- **groupItem**:分组项可以是以下之一: - - 在 `SELECT` 列表中定义的列名或别名。 - - 对 `SELECT` 列表中列位置的数字引用。 - - 任何涉及当前查询上下文中使用的表的列的表达式。 - -## 示例 - -本节中的 `GROUP BY` 示例基于以下数据设置: - -```sql --- 创建一个名为 "employees" 的示例表 -CREATE TABLE employees ( - id INT, - first_name VARCHAR(50), - last_name VARCHAR(50), - department_id INT, - job_id INT, - hire_date DATE -); - --- 向 "employees" 表中插入示例数据 -INSERT INTO employees (id, first_name, last_name, department_id, job_id, hire_date) -VALUES (1, 'John', 'Doe', 1, 101, '2021-01-15'), - (2, 'Jane', 'Smith', 1, 101, '2021-02-20'), - (3, 'Alice', 'Johnson', 1, 102, '2021-03-10'), - (4, 'Bob', 'Brown', 2, 201, '2021-03-15'), - (5, 'Charlie', 'Miller', 2, 202, '2021-04-10'), - (6, 'Eve', 'Davis', 2, 202, '2021-04-15'); -``` - -### 按单列分组 - -此查询按 `department_id` 对员工进行分组,并计算每个部门的员工人数: -```sql -SELECT department_id, COUNT(*) AS num_employees -FROM employees -GROUP BY department_id; -``` - -输出: -```sql -+---------------+---------------+ -| department_id | num_employees | -+---------------+---------------+ -| 1 | 3 | -| 2 | 3 | -+---------------+---------------+ -``` - -### 按多列分组 - -此查询按 `department_id` 和 `job_id` 对员工进行分组,然后计算每个组中的员工人数: -```sql -SELECT department_id, job_id, COUNT(*) AS num_employees -FROM employees -GROUP BY department_id, job_id; -``` - -输出: -```sql -+---------------+--------+---------------+ -| department_id | job_id | num_employees | -+---------------+--------+---------------+ -| 1 | 101 | 2 | -| 1 | 102 | 1 | -| 2 | 201 | 1 | -| 2 | 202 | 2 | -+---------------+--------+---------------+ -``` - -### 按 ALL 分组 - -此查询使用 `GROUP BY ALL` 子句对员工进行分组,该子句会对 `SELECT` 列表中的所有非聚合列进行分组。请注意,在这种情况下,结果将与按 `department_id` 和 `job_id` 分组相同,因为它们是 `SELECT` 列表中唯一的非聚合项。 - -```sql -SELECT department_id, job_id, COUNT(*) AS num_employees -FROM employees -GROUP BY ALL; -``` - -输出: -```sql -+---------------+--------+---------------+ -| department_id | job_id | num_employees | -+---------------+--------+---------------+ -| 1 | 101 | 2 | -| 1 | 102 | 1 | -| 2 | 201 | 1 | -| 2 | 202 | 2 | -+---------------+--------+---------------+ -``` - - -### 按位置分组 - -此查询等同于上面的 "按单列分组" 示例。位置 1 指的是 `SELECT` 列表中的第一项,即 `department_id`: -```sql -SELECT department_id, COUNT(*) AS num_employees -FROM employees -GROUP BY 1; -``` - -输出: -```sql -+---------------+---------------+ -| department_id | num_employees | -+---------------+---------------+ -| 1 | 3 | -| 2 | 3 | -+---------------+---------------+ -``` - -### 按表达式分组 - -此查询按员工被雇佣的年份进行分组,并计算每年雇佣的员工人数: -```sql -SELECT EXTRACT(YEAR FROM hire_date) AS hire_year, COUNT(*) AS num_hires -FROM employees -GROUP BY EXTRACT(YEAR FROM hire_date); -``` - -输出: -```sql -+-----------+-----------+ -| hire_year | num_hires | -+-----------+-----------+ -| 2021 | 6 | -+-----------+-----------+ -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/00-basics/index.md b/docs/cn/guides/54-query/00-basics/index.md deleted file mode 100644 index 5a70b1eb54..0000000000 --- a/docs/cn/guides/54-query/00-basics/index.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: 基础查询 ---- - -掌握在 Databend 中查询(Query)数据的基本方法。如果你是 SQL 新手或需要复习核心概念,可以从这里开始。 - -## 你将学到 - -- 高效地选择和筛选数据 -- 对查询结果进行排序和限制 -- 对数据进行分组和聚合计算 -- 使用高级分组技巧 - -## 查询要点 - -### [筛选与选择](./filtering-selection.md) -学习基础知识:SELECT、WHERE、ORDER BY 和 LIMIT -```sql -SELECT name, salary FROM employees -WHERE department = 'Engineering' -ORDER BY salary DESC; -``` - -### [聚合数据](./aggregating-data.md) -使用 GROUP BY 和聚合函数(Aggregate Functions)汇总数据 -```sql -SELECT department, AVG(salary) as avg_salary -FROM employees -GROUP BY department; -``` - -### [高级分组](./groupby/index.md) -使用 CUBE、ROLLUP 和 GROUPING SETS 进行多维分析 -```sql --- 生成所有可能的分组组合 -SELECT department, job_level, COUNT(*) -FROM employees -GROUP BY CUBE(department, job_level); -``` - -## 快速参考 - -### 最常用模式 -```sql --- Top N 查询 -SELECT * FROM table ORDER BY column DESC LIMIT 10; - --- 按类别计数 -SELECT category, COUNT(*) FROM table GROUP BY category; - --- 筛选和聚合 -SELECT region, AVG(sales) -FROM orders -WHERE order_date >= '2023-01-01' -GROUP BY region -HAVING AVG(sales) > 1000; -``` - -## 后续步骤 - -熟悉基础查询后,你可以继续学习: -- [组合数据](../01-combining-data/index.md) - 连接(JOIN)表和使用公共表表达式(CTE) -- [高级功能](../02-advanced/index.md) - 自定义函数和存储过程 \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-combining-data/_category_.json b/docs/cn/guides/54-query/01-combining-data/_category_.json deleted file mode 100644 index 88f5e0ae41..0000000000 --- a/docs/cn/guides/54-query/01-combining-data/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "合并数据", - "position": 2 -} \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-combining-data/cte.md b/docs/cn/guides/54-query/01-combining-data/cte.md deleted file mode 100644 index 2e90000c94..0000000000 --- a/docs/cn/guides/54-query/01-combining-data/cte.md +++ /dev/null @@ -1,94 +0,0 @@ ---- -title: 公用表表达式(CTE) ---- - -CTE 通过 `WITH` 将复杂查询拆解为简单、易读的步骤。 - -## 快速入门 - -```sql --- 替代复杂嵌套查询 -WITH high_earners AS ( - SELECT * FROM employees WHERE salary > 70000 -) -SELECT department, COUNT(*) -FROM high_earners -GROUP BY department; -``` - -**结果**:代码清晰易读,调试方便。 - -## 何时使用 CTE - -**✅ 使用 CTE:** -- 查询包含多个步骤 -- 同一子查询需使用两次 -- 查询难以阅读 - -**❌ 跳过 CTE:** -- 简单单步查询 -- 性能至关重要 - -## 三种核心模式 - -### 1. 筛选 → 分析 -```sql -WITH filtered_data AS ( - SELECT * FROM sales WHERE date >= '2023-01-01' -) -SELECT product, SUM(amount) -FROM filtered_data -GROUP BY product; -``` - -### 2. 多步处理 -```sql -WITH step1 AS ( - SELECT department, AVG(salary) as avg_sal FROM employees GROUP BY department -), -step2 AS ( - SELECT * FROM step1 WHERE avg_sal > 70000 -) -SELECT * FROM step2; -``` - -### 3. 复用同一份数据 -```sql -WITH dept_stats AS ( - SELECT department, AVG(salary) as avg_sal FROM employees GROUP BY department -) -SELECT d1.department, d1.avg_sal -FROM dept_stats d1 -JOIN dept_stats d2 ON d1.avg_sal > d2.avg_sal; -``` - -## 进阶:递归 CTE - -递归 CTE 解决需要反复应用同一逻辑的问题。想象爬楼梯:从第 1 级开始,每次向上 1 级。 - -```sql --- 生成序列(用于报表、测试或填补空缺) -WITH RECURSIVE countdown AS ( - -- 基例:起点 - SELECT 10 as num, 'Starting countdown' as message - - UNION ALL - - -- 递归:重复动作 - SELECT num - 1, CONCAT('Count: ', CAST(num - 1 AS VARCHAR)) - FROM countdown - WHERE num > 1 -- 终止条件 -) -SELECT num, message FROM countdown; -``` - -**结果**:数字从 10 倒数到 1,并附带消息。 - -**真实场景**:为销售报表补全缺失月份 -- 起点:2024-01 -- 重复:加一个月 -- 终点:2024-12 - -**核心思想**:递归 = 起点 + 重复动作 + 终止条件。 - -**到此为止。** 从简单 CTE 开始,仅在需要时增加复杂度。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-combining-data/index.md b/docs/cn/guides/54-query/01-combining-data/index.md deleted file mode 100644 index f8da5cca73..0000000000 --- a/docs/cn/guides/54-query/01-combining-data/index.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -title: 合并数据 ---- - -学习如何使用 JOIN、公用表表达式(CTE)和高级查询结构来合并多个数据源的数据。 - -## 核心概念 - -### [JOIN](./joins.md) -连接多个表的数据 -```sql --- 内连接(Inner Join)(最常用) -SELECT e.name, d.department_name -FROM employees e -JOIN departments d ON e.dept_id = d.id; -``` -**涵盖**:Inner、Left、Right、Full Outer、Semi、Anti 和 AsOf 连接 - -### [公用表表达式(Common Table Expressions, CTE)](./cte.md) -使用 WITH 子句构建复杂查询 -```sql --- 将复杂逻辑拆分为多个步骤 -WITH high_performers AS ( - SELECT * FROM employees WHERE rating > 4.0 -) -SELECT department, COUNT(*) -FROM high_performers -GROUP BY department; -``` -**涵盖**:基本 CTE、递归 CTE、物化 CTE - -## 高级组合 - -### 子查询 -```sql --- 相关子查询 -SELECT name, salary, - (SELECT AVG(salary) FROM employees e2 - WHERE e2.department = e1.department) as dept_avg -FROM employees e1; - --- EXISTS 子句 -SELECT * FROM customers c -WHERE EXISTS ( - SELECT 1 FROM orders o - WHERE o.customer_id = c.id -); -``` - -### 集合操作 -```sql --- 合并多个查询的结果 -SELECT name FROM employees WHERE department = 'Sales' -UNION -SELECT name FROM contractors WHERE active = true; - --- 其他集合操作 -INTERSECT -- 仅共同行 -EXCEPT -- 第一个查询有而第二个查询没有的行 -``` - -## 实践模式 - -### 数据增强 -```sql --- 向主表添加查找数据 -WITH region_lookup AS ( - SELECT zip_code, region_name - FROM zip_regions -) -SELECT - c.customer_name, - c.zip_code, - r.region_name, - SUM(o.amount) as total_sales -FROM customers c -LEFT JOIN region_lookup r ON c.zip_code = r.zip_code -LEFT JOIN orders o ON c.id = o.customer_id -GROUP BY c.customer_name, c.zip_code, r.region_name; -``` - -### 层级数据 -```sql --- 用于组织结构的递归 CTE -WITH RECURSIVE org_chart AS ( - -- 基本情况:顶级管理者 - SELECT id, name, manager_id, 1 as level - FROM employees WHERE manager_id IS NULL - - UNION ALL - - -- 递归情况:添加直接下属 - SELECT e.id, e.name, e.manager_id, o.level + 1 - FROM employees e - JOIN org_chart o ON e.manager_id = o.id -) -SELECT * FROM org_chart ORDER BY level, name; -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-combining-data/joins.md b/docs/cn/guides/54-query/01-combining-data/joins.md deleted file mode 100644 index 7dc25d3571..0000000000 --- a/docs/cn/guides/54-query/01-combining-data/joins.md +++ /dev/null @@ -1,200 +0,0 @@ ---- -title: JOINs ---- - -JOIN 用于将两个表中的行组合起来,创建一个新的组合行,以便在查询(Query)中使用。 - -## 简介 - -当数据分散在多个相关表中时,JOIN 非常有用。例如,一个表存储员工信息,另一个表存储部门详情。 - -我们来看一下示例数据: - -**员工表(Employees Table):** -```sql -SELECT * FROM employees ORDER BY id; -``` - -| id | name | department | salary | -|----|-------|-------------|----------| -| 1 | Alice | Engineering | 75000.00 | -| 2 | Bob | Engineering | 80000.00 | -| 3 | Carol | Marketing | 65000.00 | -| 4 | David | Sales | 70000.00 | -| 5 | Eve | Marketing | 68000.00 | - -**部门表(Departments Table):** -```sql -SELECT * FROM departments ORDER BY id; -``` - -| id | name | budget | -|----|-------------|------------| -| 1 | Engineering | 1000000.00 | -| 2 | Marketing | 500000.00 | -| 3 | Sales | 750000.00 | - -这两个表有一个共同的关系:`employees.department` 与 `departments.name` 匹配。JOIN 让我们能够组合这些相关数据。 - -## JOIN 的类型 - -### 内连接(INNER JOIN) - -内连接(INNER JOIN)将一个表中的每一行与另一个表中的匹配行配对。 - -```sql --- 获取员工及其部门预算 -SELECT e.name, e.salary, d.name as department_name, d.budget -FROM employees e -INNER JOIN departments d ON e.department = d.name -ORDER BY e.name; -``` - -**输出:** -| name | salary | department_name | budget | -|-------|----------|-----------------|------------| -| Alice | 75000.00 | Engineering | 1000000.00 | -| Bob | 80000.00 | Engineering | 1000000.00 | -| Carol | 65000.00 | Marketing | 500000.00 | -| David | 70000.00 | Sales | 750000.00 | -| Eve | 68000.00 | Marketing | 500000.00 | - -输出仅包含 `employees.department` 和 `departments.name` 之间存在匹配的行。 - -### 左连接(LEFT JOIN) - -左连接(LEFT JOIN)返回左表中的所有行,以及右表中匹配的数据。如果没有匹配项,右表的列将包含 NULL。 - -```sql --- 获取所有员工,并显示其部门预算(如果可用) -SELECT e.name, e.department, d.budget -FROM employees e -LEFT JOIN departments d ON e.department = d.name -ORDER BY e.name; -``` - -**输出:** -| name | department | budget | -|-------|-------------|------------| -| Alice | Engineering | 1000000.00 | -| Bob | Engineering | 1000000.00 | -| Carol | Marketing | 500000.00 | -| David | Sales | 750000.00 | -| Eve | Marketing | 500000.00 | - -所有员工都会显示,即使他们所在的部门不存在(此时预算将为 NULL)。 - -### 右连接(RIGHT JOIN) - -右连接(RIGHT JOIN)返回右表中的所有行,以及左表中匹配的数据。 - -```sql --- 获取所有部门,并显示其中的员工(如果有) -SELECT d.name as department_name, e.name as employee_name -FROM employees e -RIGHT JOIN departments d ON e.department = d.name -ORDER BY d.name, e.name; -``` - -**输出:** -| department_name | employee_name | -|-----------------|---------------| -| Engineering | Alice | -| Engineering | Bob | -| Marketing | Carol | -| Marketing | Eve | -| Sales | David | - -所有部门都会显示,即使部门中没有员工(此时 employee_name 将为 NULL)。 - -### 全连接(FULL JOIN) - -全连接(FULL JOIN)返回两个表中的所有行,并在可能的情况下进行匹配。 - -```sql --- 获取所有员工和所有部门 -SELECT e.name as employee_name, d.name as department_name -FROM employees e -FULL JOIN departments d ON e.department = d.name -ORDER BY e.name, d.name; -``` - -**输出:** -| employee_name | department_name | -|---------------|-----------------| -| Alice | Engineering | -| Bob | Engineering | -| Carol | Marketing | -| David | Sales | -| Eve | Marketing | - -显示所有员工和部门,没有匹配项的地方为 NULL。 - -### 交叉连接(CROSS JOIN) - -交叉连接(CROSS JOIN)会创建一个笛卡尔积(Cartesian product)——第一个表中的每一行都与第二个表中的每一行组合。 - -**警告**:这可能会产生非常大的结果集。请谨慎使用。 - -```sql --- 每个员工与每个部门配对(很少使用) -SELECT e.name, d.name as department -FROM employees e -CROSS JOIN departments d -ORDER BY e.name, d.name; -``` - -**输出(部分 - 总共 15 行):** -| name | department | -|-------|-------------| -| Alice | Engineering | -| Alice | Marketing | -| Alice | Sales | -| Bob | Engineering | -| Bob | Marketing | -| Bob | Sales | -| Carol | Engineering | -| ... | ... | - -**结果**:5 名员工 × 3 个部门 = 总共 15 行。 - -## JOIN 的实现 - -### 使用 ON 子句(推荐) - -```sql -SELECT e.name, d.budget -FROM employees e -JOIN departments d ON e.department = d.name; -``` - -### 使用 WHERE 子句(旧式) - -```sql -SELECT e.name, d.budget -FROM employees e, departments d -WHERE e.department = d.name; -``` - -**建议**:使用 ON 子句语法,因为它更清晰,并且能正确处理外连接。 - -## 多表 JOIN - -你可以将多个 JOIN 链接在一起,以组合来自两个以上表的数据: - -```sql --- 获取员工、部门预算和项目信息(如果存在 projects 表) -SELECT e.name, d.name as department, d.budget -FROM employees e -JOIN departments d ON e.department = d.name -JOIN projects p ON d.id = p.department_id -WHERE p.status = 'Active'; -``` - -## 何时使用各种 JOIN 类型 - -- **内连接(INNER JOIN)**:当你只需要两个表中都匹配的记录时。 -- **左连接(LEFT JOIN)**:当你需要左表中的所有记录,并尽可能匹配右表时。 -- **右连接(RIGHT JOIN)**:当你需要右表中的所有记录,并尽可能匹配左表时。 -- **全连接(FULL JOIN)**:当你需要两个表中的所有记录时。 -- **交叉连接(CROSS JOIN)**:很少使用;仅在明确需要笛卡尔积(Cartesian product)时使用。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/01-combining-data/subqueries.md b/docs/cn/guides/54-query/01-combining-data/subqueries.md deleted file mode 100644 index 0e013a5810..0000000000 --- a/docs/cn/guides/54-query/01-combining-data/subqueries.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: 子查询(Subquery) ---- - -子查询(Subquery)是嵌套在另一条查询语句中的查询。利用子查询(Subquery)可以筛选、比较或计算依赖于主查询数据的值。 - -## 快速上手 - -```sql --- 查找薪资高于部门平均值的员工 -SELECT name, salary, department -FROM employees -WHERE salary > ( - SELECT AVG(salary) - FROM employees AS e2 - WHERE e2.department = employees.department -); -``` - -**结果**:薪资高于其所在部门平均薪资的员工。 - -## 子查询(Subquery)的类型 - -### 1. 标量子查询(Scalar Subquery)(单值) -```sql --- 与公司整体平均薪资比较 -SELECT name, salary, - (SELECT AVG(salary) FROM employees) AS company_avg -FROM employees -WHERE salary > (SELECT AVG(salary) FROM employees); -``` - -**返回**:单个值(一行一列)。 - -### 2. 表子查询(Table Subquery)(多行) -```sql --- 按部门条件筛选 -SELECT name, department -FROM employees -WHERE department IN ( - SELECT name - FROM departments - WHERE budget > 500000 -); -``` - -**返回**:多行,可与 IN、EXISTS、ANY、ALL 等运算符配合使用。 - -## 子查询(Subquery)的位置 - -### WHERE 子句——用于筛选 -```sql --- 查询高预算部门的员工 -SELECT name, salary -FROM employees -WHERE department IN ( - SELECT name FROM departments WHERE budget > 500000 -); -``` - -### FROM 子句——作为数据源 -```sql --- 按部门分析高收入员工 -SELECT department, AVG(salary) AS avg_salary -FROM ( - SELECT * FROM employees WHERE salary > 70000 -) AS high_earners -GROUP BY department; -``` - -### SELECT 子句——作为计算列 -```sql --- 显示薪资与部门平均薪资的对比 -SELECT name, salary, - (SELECT AVG(salary) - FROM employees e2 - WHERE e2.department = e1.department) AS dept_avg -FROM employees e1; -``` - -## 相关子查询(Correlated Subquery)与非相关子查询(Uncorrelated Subquery) - -### 非相关子查询(Uncorrelated Subquery)——独立 -```sql --- 子查询仅执行一次 -SELECT name, salary -FROM employees -WHERE salary > (SELECT AVG(salary) FROM employees); -``` - -**性能**:子查询(Subquery)执行一次,结果复用。 - -### 相关子查询(Correlated Subquery)——依赖外部 -```sql --- 子查询对外部查询的每一行都执行一次 -SELECT name, salary, department -FROM employees e1 -WHERE salary > ( - SELECT AVG(salary) - FROM employees e2 - WHERE e2.department = e1.department -); -``` - -**性能**:子查询(Subquery)对外部查询的每一行都执行一次。 - -## 常见模式 - -### EXISTS——检查相关数据 -```sql --- 查询有项目参与的员工 -SELECT name, department -FROM employees e -WHERE EXISTS ( - SELECT 1 FROM projects p WHERE p.employee_id = e.id -); -``` - -### NOT EXISTS——检查缺失数据 -```sql --- 查询无项目参与的员工 -SELECT name, department -FROM employees e -WHERE NOT EXISTS ( - SELECT 1 FROM projects p WHERE p.employee_id = e.id -); -``` - -### ANY/ALL——多重比较 -```sql --- 查询薪资高于市场部(Marketing)任意员工的员工 -SELECT name, salary -FROM employees -WHERE salary > ANY ( - SELECT salary FROM employees WHERE department = 'Marketing' -); - --- 查询薪资高于市场部(Marketing)所有员工的员工 -SELECT name, salary -FROM employees -WHERE salary > ALL ( - SELECT salary FROM employees WHERE department = 'Marketing' -); -``` - -## 何时使用子查询(Subquery)与 JOIN - -**✅ 使用子查询(Subquery)的场景:** -- 基于聚合条件进行筛选 -- 检查存在/不存在 -- 需要在 SELECT 中计算值 -- 逻辑以嵌套步骤呈现更清晰 - -**✅ 使用 JOIN 的场景:** -- 需要来自多个表的列 -- 大数据集性能更佳 -- 目的在于合并数据而非筛选 \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/_category_.json b/docs/cn/guides/54-query/02-advanced/_category_.json deleted file mode 100644 index 7b53af6258..0000000000 --- a/docs/cn/guides/54-query/02-advanced/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "高级功能", - "position": 3 -} \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/external-function.md b/docs/cn/guides/54-query/02-advanced/external-function.md deleted file mode 100644 index 63f4b354fc..0000000000 --- a/docs/cn/guides/54-query/02-advanced/external-function.md +++ /dev/null @@ -1,224 +0,0 @@ ---- -title: "Databend Cloud 中的外部函数" -sidebar_label: "外部函数" -sidebar_position: 2 ---- - -Databend 中的外部函数(External Function)允许你使用 Python 等编程语言编写的外部服务器来定义处理数据的自定义操作。这些函数通过集成自定义逻辑、利用外部库和处理复杂任务,帮助你扩展 Databend 的能力。外部函数的主要特点包括: - -- **可扩展性**:非常适合复杂且资源密集的数据操作。 -- **外部库**:通过外部库和依赖项利用额外功能。 -- **高级逻辑**:为复杂场景实现复杂的数据处理逻辑。 - -## 支持的编程语言 - -下表列出了在 Databend 中创建外部函数所支持的语言及所需库: - -| 语言 | 所需库 | -| -------- | ----------------------------------------------------- | -| Python | [databend-udf](https://pypi.org/project/databend-udf) | - -## 管理外部函数 - -你可以使用 `CREATE FUNCTION`、`DROP FUNCTION` 和 `SHOW FUNCTIONS` 等 SQL 命令管理外部函数。更多详情,请参见 [外部函数](/sql/sql-commands/ddl/external-function/)。 - -## 在 Databend Cloud 中配置外部函数 - -要在 Databend Cloud 中使用外部函数,你需要**将外部函数服务器地址加入白名单**。外部函数服务器必须通过域名以 HTTPS 方式访问。请联系 Databend Cloud 支持团队,添加你允许的 UDF 服务器地址: - -1. 在 Databend Cloud 控制台中,导航到 **支持** > **创建新工单**。 -2. 提供你希望加入白名单的外部服务器地址(使用 HTTPS 域名)。 -3. 提交工单并等待支持团队确认。 - -## 使用示例:用 Python 创建外部函数 - -本节演示如何使用 Python 创建外部函数。 - -### 1. 安装所需库 - -使用 `pip` 安装 [databend-udf](https://pypi.org/project/databend-udf) 库: - -```bash -pip install databend-udf -``` - -### 2. 定义函数 - -创建 Python 文件(例如 `external_function.py`)并定义外部函数。以下示例定义了一个 Python 外部服务器,公开自定义函数 `gcd`,用于计算两个整数的最大公约数: - -```python -from databend_udf import udf, UDFServer - -@udf( - input_types=["INT", "INT"], - result_type="INT", - skip_null=True, -) -def gcd(x: int, y: int) -> int: - while y != 0: - x, y = y, x % y - return x - -if __name__ == '__main__': - # 创建监听 '0.0.0.0:8815' 的外部服务器 - server = UDFServer("0.0.0.0:8815") - # 添加已定义函数 - server.add_function(gcd) - # 启动外部服务器 - server.serve() -``` - -**`@udf` 装饰器参数说明:** - -| 参数 | 描述 | -| ------------- | ------------------------------------------------------------------------------------------------------------------------------------ | -| `input_types` | 字符串列表,指定输入数据类型(例如 `["INT", "VARCHAR"]`)。 | -| `result_type` | 字符串,指定返回值类型(例如 `"INT"`)。 | -| `name` | (可选)函数自定义名称。若未提供,则使用原始函数名。 | -| `io_threads` | 每个数据块用于 I/O 密集型函数的 I/O 线程数。 | -| `skip_null` | 若设为 `True`,NULL 值不会传递给函数,对应返回值设为 NULL。默认为 `False`。 | - -**Databend 与 Python 的数据类型映射:** - -| Databend 类型 | Python 类型 | -| ------------------- | ------------------- | -| BOOLEAN | `bool` | -| TINYINT (UNSIGNED) | `int` | -| SMALLINT (UNSIGNED) | `int` | -| INT (UNSIGNED) | `int` | -| BIGINT (UNSIGNED) | `int` | -| FLOAT | `float` | -| DOUBLE | `float` | -| DECIMAL | `decimal.Decimal` | -| DATE | `datetime.date` | -| TIMESTAMP | `datetime.datetime` | -| VARCHAR | `str` | -| VARIANT | `any` | -| MAP(K,V) | `dict` | -| ARRAY(T) | `list[T]` | -| TUPLE(T,...) | `tuple(T,...)` | - -### 3. 运行外部服务器 - -运行 Python 文件启动外部服务器: - -```bash -python3 external_function.py -``` - -**注意:** 确保服务器可从 Databend Cloud 访问且地址已加入白名单。若尚未完成,请联系 Databend Cloud 支持团队将服务器地址添加到白名单。 - -### 4. 在 Databend Cloud 中注册函数 - -使用 `CREATE FUNCTION` 语句在 Databend 中注册 `gcd` 函数: - -```sql -CREATE FUNCTION gcd (INT, INT) - RETURNS INT - LANGUAGE PYTHON - HANDLER = 'gcd' - ADDRESS = ''; -``` - -- 将 `` 替换为已在 Databend Cloud 白名单中的外部服务器实际地址(必须为 HTTPS 域名)。 -- `HANDLER` 指定 Python 代码中定义的函数名称。 -- `ADDRESS` 必须与外部服务器运行地址一致,且已被 Databend Cloud 加入白名单。 - -**示例:** - -```sql -CREATE FUNCTION gcd (INT, INT) - RETURNS INT - LANGUAGE PYTHON - HANDLER = 'gcd' - ADDRESS = 'https://your-server-address'; -``` - -**重要:** 执行此语句前,请确保通过联系支持团队将 `'https://your-server-address'` 加入 Databend Cloud 白名单。 - -现在你可以在 SQL 查询中使用外部函数 `gcd`: - -```sql -SELECT gcd(48, 18); -- 返回 6 -``` - -## 外部函数负载均衡 - -部署多个外部函数服务器时,可根据函数名称实现负载均衡。Databend 在每个 UDF 请求中包含 `X-DATABEND-FUNCTION` 标头,内容为被调用函数的小写名称。此标头可用于将请求路由到不同后端服务器。 - -### 使用 Nginx 进行基于函数的路由 - -以下示例展示如何配置 Nginx,将不同 UDF 请求路由到特定后端服务器: - -```nginx -# 为不同 UDF 函数定义上游服务器 -upstream udf_default { - server 10.0.0.1:8080; - server 10.0.0.2:8080 backup; -} - -upstream udf_math_functions { - server 10.0.1.1:8080; - server 10.0.1.2:8080 backup; -} - -upstream udf_string_functions { - server 10.0.2.1:8080; - server 10.0.2.2:8080 backup; -} - -upstream udf_database_functions { - server 10.0.3.1:8080; - server 10.0.3.2:8080 backup; -} - -# 将函数名称映射到后端服务器 -map $http_x_databend_function $udf_backend { - default "udf_default"; - gcd "udf_math_functions"; - lcm "udf_math_functions"; - string_* "udf_string_functions"; - *_db "udf_database_functions"; -} - -# 服务器配置 -server { - listen 443 ssl; - server_name udf.example.com; - - # SSL 配置 - ssl_certificate /etc/nginx/ssl/udf.example.com.crt; - ssl_certificate_key /etc/nginx/ssl/udf.example.com.key; - - # 安全标头 - add_header Strict-Transport-Security "max-age=31536000" always; - - location / { - proxy_pass http://$udf_backend; - proxy_http_version 1.1; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto $scheme; - - # 超时设置 - proxy_connect_timeout 60s; - proxy_send_timeout 60s; - proxy_read_timeout 60s; - } -} -``` - -在 Databend 中注册函数时,请使用 Nginx 服务器的域名: - -```sql -CREATE FUNCTION gcd (INT, INT) - RETURNS INT - LANGUAGE PYTHON - HANDLER = 'gcd' - ADDRESS = 'https://udf.example.com'; -``` - -## 总结 - -Databend Cloud 中的外部函数通过集成用 Python 等语言编写的自定义代码,为扩展数据处理 Pipeline 功能提供了强大方式。按照上述步骤,你可以创建并使用外部函数处理复杂任务、利用外部库并实现高级逻辑。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/index.md b/docs/cn/guides/54-query/02-advanced/index.md deleted file mode 100644 index 58edccbbf0..0000000000 --- a/docs/cn/guides/54-query/02-advanced/index.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -title: 高级功能 ---- - -通过自定义函数、外部集成、存储过程和序列(Sequence)扩展 Databend 的能力。 - -## [用户定义函数(UDF)](./udf.md) -使用 SQL、Python 或 JavaScript 创建可复用的自定义函数。 -```sql --- SQL 函数 -CREATE FUNCTION calculate_bonus(salary FLOAT, rating FLOAT) -RETURNS FLOAT AS $$ salary * rating * 0.1 $$; - --- 使用函数 -SELECT name, calculate_bonus(salary, performance_rating) as bonus -FROM employees; -``` - -## [外部函数](./external-function.md) -与外部服务和 API 集成。 -```sql --- 调用外部机器学习模型 -SELECT customer_id, predict_churn(age, tenure, usage) as churn_risk -FROM customers; -``` - -## [存储过程](./stored-procedure.md) -支持控制流的多步操作。 -```sql --- 复杂的业务逻辑 -CALL monthly_report_generation('2023-12'); -``` - -## [序列(Sequence)](./sequences.md) -生成唯一标识符和序列值。 -```sql --- 创建自增 ID -CREATE SEQUENCE user_id_seq; -INSERT INTO users VALUES (NEXTVAL(user_id_seq), 'John Doe'); -``` - - -## 最佳实践 - -### 函数设计 -- **保持函数纯粹** - 相同输入始终产生相同输出。 -- **处理 NULL 值** - 考虑 NULL 输入的处理方式。 -- **使用合适类型** - 使输入/输出类型与使用场景匹配。 -- **完善文档** - 清晰描述参数和返回值。 - -### 性能考量 -- **UDF 开销** - SQL 函数最快,Python/JS 较慢。 -- **批量操作** - 尽可能批量处理数据。 -- **资源限制** - 监控复杂函数的内存使用。 - -### 安全性 -- **验证输入** - 在 UDF 代码中检查参数。 -- **最小权限** - 外部连接应仅拥有必要权限。 -- **审计使用** - 监控 UDF 和外部函数的调用。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/sequences.md b/docs/cn/guides/54-query/02-advanced/sequences.md deleted file mode 100644 index f6df5602b9..0000000000 --- a/docs/cn/guides/54-query/02-advanced/sequences.md +++ /dev/null @@ -1,134 +0,0 @@ ---- -title: 序列(Sequence) -sidebar_position: 4 ---- - -序列(Sequence)用于生成唯一的、连续的数值,通常用于主键(Primary Key)和自增标识符。 - -## 什么是序列(Sequence)? - -序列(Sequence)提供了一种线程安全的方式,用于在并发操作中生成唯一的数字。与自增列不同,序列(Sequence)是数据库对象,可以在多个表之间共享使用。 - -## 创建序列(Sequence) - -### 基本序列(Sequence) -```sql --- 创建一个简单的序列 -CREATE SEQUENCE user_id_seq; - --- 使用序列 -SELECT NEXTVAL(user_id_seq); -- 返回: 1 -SELECT NEXTVAL(user_id_seq); -- 返回: 2 -SELECT NEXTVAL(user_id_seq); -- 返回: 3 -``` - -### 带选项的序列(Sequence) -```sql --- 创建带自定义设置的序列 -CREATE SEQUENCE order_id_seq - START = 1000 - INCREMENT = 1 - MINVALUE = 1000 - MAXVALUE = 999999999 - CACHE = 50; -``` - -## 使用序列(Sequence) - -### 在 INSERT 语句中使用 -```sql --- 创建使用序列生成 ID 的表 -CREATE TABLE users ( - id BIGINT, - name VARCHAR(100), - email VARCHAR(100) -); - --- 使用序列值插入数据 -INSERT INTO users VALUES - (NEXTVAL(user_id_seq), 'John Doe', 'john@example.com'), - (NEXTVAL(user_id_seq), 'Jane Smith', 'jane@example.com'); -``` - -### 当前值与下一个值 -```sql --- 获取下一个值(序列会前进) -SELECT NEXTVAL(user_id_seq); - --- 获取当前值(序列不会前进) -SELECT CURRVAL(user_id_seq); -``` - -## 序列(Sequence)函数 - -| 函数 | 描述 | 示例 | -|----------|-------------|---------| -| `NEXTVAL(seq)` | 获取下一个值并推进序列 | `NEXTVAL(user_id_seq)` | -| `CURRVAL(seq)` | 获取当前值,不推进序列 | `CURRVAL(user_id_seq)` | - -## 管理序列(Sequence) - -### 查看序列(Sequence) -```sql --- 显示所有序列 -SHOW SEQUENCES; - --- 查看特定序列的描述 -DESC SEQUENCE user_id_seq; -``` - -### 修改序列(Sequence) -```sql --- 将序列重置为特定值 -ALTER SEQUENCE user_id_seq RESTART = 5000; - --- 更改增量值 -ALTER SEQUENCE user_id_seq INCREMENT = 10; -``` - -### 删除序列(Sequence) -```sql --- 移除序列 -DROP SEQUENCE user_id_seq; -``` - -## 最佳实践 - -### 性能优化 -- **使用 CACHE** - 通过预分配值来提高性能 -- **适当的 INCREMENT** - 匹配你的应用需求 -- **监控间隙** - 如果服务器重启,缓存的值可能会产生间隙 - -### 常见模式 -```sql --- 自增主键模式 -CREATE SEQUENCE pk_seq START = 1 INCREMENT = 1 CACHE = 100; - -CREATE TABLE products ( - id BIGINT DEFAULT NEXTVAL(pk_seq), - name VARCHAR(100), - price DECIMAL(10,2) -); - --- 订单号模式(可读 ID) -CREATE SEQUENCE order_seq START = 10000 INCREMENT = 1; - -INSERT INTO orders VALUES - (NEXTVAL(order_seq), customer_id, order_date); -``` - -## 与自增列的对比 - -| 特性 | 序列(Sequence) | 自增(Auto-Increment) | -|---------|-----------|----------------| -| **可重用性** | ✅ 多个表 | ❌ 单个列 | -| **控制** | ✅ 完全控制 | ❌ 选项有限 | -| **间隙** | ✅ 可预测 | ❌ 可能有间隙 | -| **性能** | ✅ 可缓存 | ✅ 已优化 | - -## 常见用例 - -1. **主键(Primary Key)** - 跨表的唯一标识符 -2. **订单号** - 连续的业务标识符 -3. **版本号** - 文档或记录的版本控制 -4. **批次 ID** - 处理批次的标识 \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/stored-procedure.md b/docs/cn/guides/54-query/02-advanced/stored-procedure.md deleted file mode 100644 index 692db2b483..0000000000 --- a/docs/cn/guides/54-query/02-advanced/stored-procedure.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 存储过程(Stored Procedure) -sidebar_position: 3 ---- - -存储过程(Stored Procedure)是存储在数据库中的一组可执行命令或逻辑块,使用 SQL 或其他编程语言编写,旨在可重复使用以高效执行特定任务或操作。 - -## 支持的语言 - -**Databend 目前仅支持 [SQL 脚本](/sql/stored-procedure-scripting/)**。使用 SQL 脚本,用户可以定义带有控制流结构的过程,如循环(FOR、WHILE、REPEAT)和条件语句(IF、CASE),从而实现复杂逻辑和有效的多步骤操作。 - -## 限制 - -使用存储过程时存在以下限制: - -- 存储过程是实验性功能。在使用之前,需要将 `enable_experimental_procedure` 设置为 1; - - ```sql - SET enable_experimental_procedure = 1; - ``` - -- 存储过程以字符串形式返回结果,无论指定的返回类型是什么,都不会对返回值强制执行声明的类型。 - -## 管理存储过程 - -Databend 提供了一系列用于管理存储过程的命令。有关更多详细信息,请参阅[存储过程](/sql/sql-commands/ddl/procedure/)。 - -## 使用示例 - -假设我们想要计算给定范围内所有偶数的总和。此存储过程接受起始值 start_val 和结束值 end_val,并计算此范围内所有偶数的总和。 - -```sql -SET enable_experimental_procedure = 1; - -CREATE PROCEDURE sum_even_numbers(start_val UInt8, end_val UInt8) -RETURNS UInt8 NOT NULL -LANGUAGE SQL -COMMENT='计算所有偶数的总和' -AS $$ -BEGIN - LET sum := 0; - FOR i IN start_val TO end_val DO - IF i % 2 = 0 THEN - sum := sum + i; - END IF; - END FOR; - - RETURN sum; -END; -$$; -``` - -如果我们想要计算从 1 到 10 的所有偶数的总和,可以按如下方式调用该过程: - -```sql -CALL PROCEDURE sum_even_numbers(1, 10); - --- 结果:2 + 4 + 6 + 8 + 10 = 30 -┌────────┐ -│ Result │ -├────────┤ -│ 30 │ -└────────┘ -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/02-advanced/udf.md b/docs/cn/guides/54-query/02-advanced/udf.md deleted file mode 100644 index 385a45b8fb..0000000000 --- a/docs/cn/guides/54-query/02-advanced/udf.md +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: 用户自定义函数 -sidebar_position: 1 ---- - -# Databend 中的用户自定义函数(UDF) - -用户自定义函数(UDF)允许您根据特定的数据处理需求创建自定义操作。为了保持一致性,Databend 在所有函数类型中都使用了**统一的 `$$` 语法**。 - -## 快速入门指南 - -根据您需要返回的内容选择函数类型: - -| **需要返回** | **函数类型** | **文档** | -|-------------------|-------------------|-------------------| -| 单个值(数字、字符串等) | **标量 SQL** | [CREATE SCALAR FUNCTION](/sql/sql-commands/ddl/udf/ddl-create-function) | -| 多行/多列 | **表函数 SQL** | [CREATE TABLE FUNCTION](/sql/sql-commands/ddl/udf/ddl-create-table-function) | -| 使用 Python/JS/WASM 实现复杂逻辑 | **嵌入式** | [CREATE EMBEDDED FUNCTION](/sql/sql-commands/ddl/udf/ddl-create-function-embedded) | - -所有函数类型都使用相同的统一语法模式: -```sql -CREATE FUNCTION name(params) RETURNS type AS $$ logic $$; -``` - -## 标量 SQL 函数 - -使用 SQL 表达式返回单个值。非常适合用于计算、格式化和简单的转换。 - -```sql --- 计算 BMI -CREATE FUNCTION calculate_bmi(weight FLOAT, height FLOAT) -RETURNS FLOAT -AS $$ weight / (height * height) $$; - --- 格式化全名 -CREATE FUNCTION full_name(first VARCHAR, last VARCHAR) -RETURNS VARCHAR -AS $$ concat(first, ' ', last) $$; - --- 使用函数 -SELECT - full_name('John', 'Doe') AS name, - calculate_bmi(70.0, 1.75) AS bmi; -``` - - -## 表函数(UDTF) - -返回包含多行和多列的结果集。非常适合用于封装带参数的复杂查询。 - -```sql --- 按部门获取员工 -CREATE FUNCTION get_dept_employees(dept_name VARCHAR) -RETURNS TABLE (id INT, name VARCHAR, salary DECIMAL) -AS $$ - SELECT id, name, salary - FROM employees - WHERE department = dept_name -$$; - --- 部门统计 -CREATE FUNCTION dept_stats() -RETURNS TABLE (department VARCHAR, count INT, avg_salary DECIMAL) -AS $$ - SELECT department, COUNT(*), AVG(salary) - FROM employees - GROUP BY department -$$; - --- 使用表函数 -SELECT * FROM get_dept_employees('Engineering'); -SELECT * FROM dept_stats(); -``` - -## 嵌入式函数 - -对于无法用 SQL 轻松表达的复杂逻辑,可以使用 Python、JavaScript 或 WASM。 - -| 语言 | 需要企业版 | 包支持 | -|----------|-------------------|-----------------| -| Python | 是 | PyPI 包 | -| JavaScript | 否 | 否 | -| WASM | 否 | 否 | - -### Python 示例 -```sql --- 带有类型安全的简单计算 -CREATE FUNCTION py_calc(INT, INT) -RETURNS INT -LANGUAGE python HANDLER = 'calculate' -AS $$ -def calculate(x, y): - return x * y + 10 -$$; - -SELECT py_calc(5, 3); -- 返回:25 -``` - -### JavaScript 示例 -```sql --- 字符串处理 -CREATE FUNCTION js_format(VARCHAR, INT) -RETURNS VARCHAR -LANGUAGE javascript HANDLER = 'formatPerson' -AS $$ -export function formatPerson(name, age) { - return `${name} is ${age} years old`; -} -$$; - -SELECT js_format('Alice', 25); -- 返回:"Alice is 25 years old" -``` - -## 函数管理 - -| 命令 | 文档 | -|---------|--------------| -| **CREATE** 函数 | [标量](/sql/sql-commands/ddl/udf/ddl-create-function)、[表](/sql/sql-commands/ddl/udf/ddl-create-table-function)、[嵌入式](/sql/sql-commands/ddl/udf/ddl-create-function-embedded) | -| **ALTER** 函数 | [ALTER FUNCTION](/sql/sql-commands/ddl/udf/ddl-alter-function) | -| **DROP** 函数 | [DROP FUNCTION](/sql/sql-commands/ddl/udf/ddl-drop-function) | -| **SHOW** 函数 | [SHOW USER FUNCTIONS](/sql/sql-commands/ddl/udf/ddl-show-user-functions) | - -有关用户自定义函数(UDF)的完整概述和比较,请参阅 [用户自定义函数命令](/sql/sql-commands/ddl/udf/)。 \ No newline at end of file diff --git a/docs/cn/guides/54-query/03-optimization/_category_.json b/docs/cn/guides/54-query/03-optimization/_category_.json deleted file mode 100644 index d044b6f8ba..0000000000 --- a/docs/cn/guides/54-query/03-optimization/_category_.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "label": "查询优化", - "position": 4 -} \ No newline at end of file diff --git a/docs/cn/guides/54-query/03-optimization/index.md b/docs/cn/guides/54-query/03-optimization/index.md deleted file mode 100644 index 6953d41576..0000000000 --- a/docs/cn/guides/54-query/03-optimization/index.md +++ /dev/null @@ -1,201 +0,0 @@ ---- -title: 查询优化 ---- - -使用性能分析工具、执行计划和优化技术来分析和提升查询性能。 - -## 性能分析工具 - -### [查询分析](./query-profile.md) -Databend Cloud 中的可视化执行计划分析 -- **访问路径**:监控 → SQL 历史 → 查询分析标签页 -- **展示内容**:执行节点、耗时、资源使用情况 -- **用途**:识别瓶颈、理解查询执行过程 - -### [查询哈希](./query-hash.md) -用于性能追踪的唯一查询指纹 -```sql --- 获取查询指纹 -SELECT query_hash('SELECT * FROM table WHERE id = ?'); -``` - -## 查询优化基础 - -### 执行计划分析 -```sql --- 查看查询执行计划 -EXPLAIN SELECT * FROM orders o -JOIN customers c ON o.customer_id = c.id -WHERE o.order_date >= '2023-01-01'; -``` - -**关注点:** -- **表扫描** vs **索引使用** -- **连接算法**(哈希、合并、嵌套循环) -- **过滤下推**效果 -- **资源消耗**估算 - -### 索引策略 -```sql --- 为常见查询模式创建索引 -CREATE INDEX idx_orders_date ON orders(order_date); -CREATE INDEX idx_orders_customer ON orders(customer_id); -``` - -**索引指南:** -- 为 WHERE 子句中的列创建索引 -- 为 JOIN 两侧的列创建索引 -- 为多列过滤条件考虑复合索引 -- 监控索引使用统计信息 - -## 性能优化技术 - -### 查询重写 -```sql --- ❌ 低效:对列使用函数导致无法使用索引 -SELECT * FROM orders WHERE YEAR(order_date) = 2023; - --- ✅ 优化:范围条件可以使用索引 -SELECT * FROM orders -WHERE order_date >= '2023-01-01' - AND order_date < '2024-01-01'; -``` - -### 过滤下推 -```sql --- ❌ 连接后过滤 -SELECT * FROM ( - SELECT o.*, c.name - FROM orders o JOIN customers c ON o.customer_id = c.id -) WHERE order_date >= '2023-01-01'; - --- ✅ 连接前过滤 -SELECT o.*, c.name -FROM orders o -JOIN customers c ON o.customer_id = c.id -WHERE o.order_date >= '2023-01-01'; -``` - -### 聚合优化 -```sql --- 使用合适的 GROUP BY 扩展 -SELECT - region, - product_category, - COUNT(*) as sales_count, - SUM(amount) as total_sales -FROM sales -GROUP BY CUBE(region, product_category); -``` - -## 常见性能问题 - -### 问题 1:结果集过大 -```sql --- ❌ 问题:对大表查询未加限制 -SELECT * FROM events ORDER BY timestamp DESC; - --- ✅ 解决:始终限制探索性查询的结果集大小 -SELECT * FROM events ORDER BY timestamp DESC LIMIT 1000; -``` - -### 问题 2:低效的连接 -```sql --- ❌ 问题:笛卡尔积 -SELECT * FROM table1, table2 WHERE condition; - --- ✅ 解决:使用带有正确条件的显式连接 -SELECT * FROM table1 t1 -INNER JOIN table2 t2 ON t1.id = t2.foreign_id -WHERE condition; -``` - -### 问题 3:不必要的复杂性 -```sql --- ❌ 问题:嵌套子查询 -SELECT * FROM ( - SELECT * FROM ( - SELECT col1, col2 FROM table WHERE condition1 - ) WHERE condition2 -) WHERE condition3; - --- ✅ 解决:合并条件 -SELECT col1, col2 FROM table -WHERE condition1 AND condition2 AND condition3; -``` - -## 监控与指标 - -### 关键性能指标 -- **查询执行时间** -- **扫描行数 vs 返回行数** -- **内存使用量** -- **CPU 使用率** -- **I/O 操作** - -### 性能监控查询 -```sql --- 从查询历史中查找慢查询 -SELECT - query_text, - query_duration_ms, - scan_bytes, - result_bytes, - memory_usage -FROM system.query_log -WHERE query_duration_ms > 10000 -- 超过 10 秒的查询 -ORDER BY query_duration_ms DESC -LIMIT 10; -``` - -## 优化清单 - -### 查询设计 -- [ ] 使用合适的 WHERE 条件 -- [ ] 通过选择列来最小化扫描的数据量 -- [ ] 在连接前应用过滤器 -- [ ] 使用正确的连接类型 -- [ ] 适当限制结果集 - -### 索引 -- [ ] 为频繁过滤的列创建索引 -- [ ] 为连接列创建索引 -- [ ] 移除未使用的索引 -- [ ] 监控索引的有效性 - -### 模式设计 -- [ ] 选择合适的数据类型 -- [ ] 适当进行规范化(避免过度规范化) -- [ ] 对大表考虑使用分区 -- [ ] 使用聚簇键进行排序优化 - -## 高级优化 - -### 聚合索引 -```sql --- 使用 Databend 的聚合索引预计算昂贵的聚合操作 -CREATE AGGREGATING INDEX daily_sales_agg AS -SELECT - DATE(order_time) as order_date, - product_id, - COUNT(*) as order_count, - SUM(amount) as total_sales -FROM orders -GROUP BY DATE(order_time), product_id; -``` - -### 查询提示 -```sql --- 必要时强制使用特定的连接算法 -SELECT /*+ USE_HASH_JOIN */ * -FROM large_table l -JOIN small_table s ON l.id = s.foreign_id; -``` - -## 最佳实践总结 - -1. **首先测量** - 使用查询分析识别瓶颈 -2. **策略性地创建索引** - 覆盖你的查询模式 -3. **尽早过滤** - 尽快应用 WHERE 条件 -4. **适当限制** - 不要获取超出需要的数据 -5. **持续监控** - 长期跟踪查询性能 \ No newline at end of file diff --git a/docs/cn/guides/54-query/03-optimization/query-hash.md b/docs/cn/guides/54-query/03-optimization/query-hash.md deleted file mode 100644 index df4e3e52b9..0000000000 --- a/docs/cn/guides/54-query/03-optimization/query-hash.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: 查询哈希(Query Hash) ---- - -查询哈希(Query Hash)是用于表示唯一 SQL 查询(Query)的标识符。它将查询的结构和内容转换为一个固定长度的值,因此即使查询文本有细微差异,只要逻辑结构相同,其哈希值也会相同。这有助于识别相似查询和频繁执行的查询。 - -## 查询哈希类型 - -Databend 支持两种类型的查询哈希: - -- `query_hash`:`query_hash` 确保重复查询即使在空格或注释上存在差异,也共享相同的哈希值。例如,以下查询共享相同的哈希值: - - ```sql - SELECT * FROM t1 WHERE name = 'jim' - SELECT * FROM t1 WHERE name = 'jim' - ``` - -- `query_parameterized_hash`:`query_parameterized_hash` 通过处理比较谓词(例如 `=`、`!=`、`>=`、`<=`)中涉及的字面量来规范化查询,从而能够识别结构相似的查询,而不受所用具体值的影响。例如,以下查询共享相同的哈希值: - - ```sql - SELECT * FROM t1 WHERE name = 'data' - SELECT * FROM t1 WHERE name = 'bend' - ``` - -## 检索哈希值 - -Databend 将历史查询的哈希值存储在系统表 [system.query_log](/sql/sql-reference/system-tables/system-query-log) 中名为 `query_hash` 和 `query_parameterized_hash` 的列中。要检索查询的哈希值,您可以使用 SELECT 语句从系统表中提取它们。例如: - -```sql -SELECT * FROM books; - -┌───────────────────────────────────────────────────────────────┐ -│ id │ title │ genre │ -├──────────────────┼─────────────────────────┼──────────────────┤ -│ 1 │ To Kill a Mockingbird │ Fiction │ -│ 2 │ A Brief History of Time │ Science │ -└───────────────────────────────────────────────────────────────┘ - -SELECT query_text, query_hash, query_parameterized_hash -FROM system.query_log -WHERE query_text = 'SELECT * FROM books'; - -┌───────────────────────────────────────────────────────────────────────────────────────────┐ -│ query_text │ query_hash │ query_parameterized_hash │ -├─────────────────────┼──────────────────────────────────┼──────────────────────────────────┤ -│ SELECT * FROM books │ 7e612be4897104109449c74d3970c9e7 │ 7e612be4897104109449c74d3970c9e7 │ -│ SELECT * FROM books │ 7e612be4897104109449c74d3970c9e7 │ 7e612be4897104109449c74d3970c9e7 │ -└───────────────────────────────────────────────────────────────────────────────────────────┘ -``` - -## 示例 - -假设我们有一个包含以下行的表: - -```sql -SELECT * FROM books; - -┌───────────────────────────────────────────────────────────────┐ -│ id │ title │ genre │ -├──────────────────┼─────────────────────────┼──────────────────┤ -│ 1 │ To Kill a Mockingbird │ Fiction │ -│ 2 │ A Brief History of Time │ Science │ -└───────────────────────────────────────────────────────────────┘ -``` - -以下查询将共享相同的哈希值: - -```sql -SELECT * FROM books WHERE id = 1; -SELECT * FROM books WHERE id = 1; -``` - -检查它们: - -```sql -SELECT query_text, query_hash, query_parameterized_hash -FROM system.query_log -WHERE query_text = 'SELECT * FROM books WHERE id = 1' - OR query_text = 'SELECT * FROM books WHERE id = 1'; - -┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ query_text │ query_hash │ query_parameterized_hash │ -├──────────────────────────────────┼──────────────────────────────────┼──────────────────────────────────┤ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -└────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -``` - -以下查询共享相同的 `query_parameterized_hash` 值: - -```sql -SELECT * FROM books WHERE id = 1; -SELECT * FROM books WHERE id = 2; - -SELECT query_text, query_hash, query_parameterized_hash -FROM system.query_log -WHERE query_text = 'SELECT * FROM books WHERE id = 1' - OR query_text = 'SELECT * FROM books WHERE id = 2'; - -┌────────────────────────────────────────────────────────────────────────────────────────────────────────┐ -│ query_text │ query_hash │ query_parameterized_hash │ -├──────────────────────────────────┼──────────────────────────────────┼──────────────────────────────────┤ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 1 │ ae040c4b3a9388c75e10be76ba407b17 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 2 │ 26f135b4936d6a21922074861e5180a4 │ b68f516c17d3c15b2c070e4af528464c │ -│ SELECT * FROM books WHERE id = 2 │ 26f135b4936d6a21922074861e5180a4 │ b68f516c17d3c15b2c070e4af528464c │ -└────────────────────────────────────────────────────────────────────────────────────────────────────────┘ -``` \ No newline at end of file diff --git a/docs/cn/guides/54-query/03-optimization/query-profile.md b/docs/cn/guides/54-query/03-optimization/query-profile.md deleted file mode 100644 index 1f77215b47..0000000000 --- a/docs/cn/guides/54-query/03-optimization/query-profile.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: 查询分析(Query Profile) ---- - -查询分析(Query Profile)是指特定 SQL 语句执行方式的图形化表示或可视化分解。它本质上是 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令的图形化版本,可以深入了解查询的执行计划和性能细节。 - -## 访问查询分析(Query Profile) - -查询分析(Query Profile)可以直接在 Databend Cloud 中访问。要查看查询的查询分析(Query Profile),请前往 **监控(Monitor)** > **SQL 历史(SQL History)**。从历史记录列表中选择一个 SQL 语句,然后单击 **查询分析(Query Profile)** 选项卡。如果您使用的是自托管的 Databend,可以使用 [EXPLAIN](/sql/sql-commands/explain-cmds/explain) 命令作为替代方案。 - -## 查询分析(Query Profile)包含什么 - -以下是一个查询分析(Query Profile)的示例,由三个层级结构的算子节点(Operator Node)组成。执行 SQL 语句时,Databend Cloud 会按自下而上的顺序处理这些节点。查询分析(Query Profile)中包含的算子节点(Operator Node)的数量和类型取决于 SQL 语句的具体内容。有关常见的算子及其统计字段,请参见[常见算子和字段](#common-operators--fields)。 - -![alt text](/img/cloud/query-profile-1.png) - -*请注意,每个节点标题中括号内的数字代表节点 ID,并*不*表示执行步骤。* - -查询分析(Query Profile)附带一组提供更多详细信息的信息窗格。上面的示例包括两个信息窗格: - -| 窗格 | 描述 | -| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 开销最大的节点 | 列出执行时间最长的节点。 | -| 分析概览 | 显示 CPU 和 I/O 耗时的百分比。请注意,如果选择一个节点,此信息窗格将显示特定于所选节点的信息,而不是整个查询的信息。 | - -如果单击 `TableScan [4]` 节点,您会注意到右侧新增了两个信息窗格: - -![alt text](/img/cloud/query-profile-2.png) - -| 窗格 | 描述 | -| ---------- | ---------------------------------------------------------------------------------------------------------- | -| 统计信息 | 包括扫描进度、扫描字节数、从缓存中扫描的百分比、扫描的分区数等信息。 | -| 属性 | 显示特定于节点的详细信息。显示的字段根据节点的功能而有所不同。 | - -## 常见算子和字段 - -解释计划(Explained Plan)包括各种算子,具体取决于您希望 Databend EXPLAIN 的 SQL 语句。以下是常见算子及其字段的列表: - -* **TableScan**: 从表中读取数据。 - - table: 表的全名。例如,`catalog1.database1.table1`。 - - read rows: 要读取的行数。 - - read bytes: 要读取的数据字节数。 - - partition total: 表的总分区数。 - - partition scanned: 要读取的分区数。 - - push downs: 要下推到存储层进行处理的筛选器和限制。 -* **Filter**: 筛选读取的数据。 - - filters: 用于筛选数据的谓词表达式。表达式求值为 false 的数据将被筛选掉。 -* **EvalScalar**: 计算标量表达式。例如,`SELECT a+1 AS b FROM t` 中的 `a+1`。 - - expressions: 要计算的标量表达式。 -* **AggregatePartial** & **AggregateFinal**: 按键进行聚合,并返回聚合函数的结果。 - - group by: 用于聚合的键。 - - aggregate functions: 用于聚合的函数。 -* **Sort**: 按键对数据进行排序。 - - sort keys: 用于排序的表达式。 -* **Limit**: 限制返回的行数。 - - limit: 要返回的行数。 - - offset: 在返回任何行之前要跳过的行数。 -* **HashJoin**: 使用哈希连接(Hash Join)算法对两个表执行连接操作。哈希连接(Hash Join)算法会选择其中一个表作为构建端来构建哈希表。然后,它将使用另一个表作为探测端,从哈希表中读取匹配的数据以形成结果。 - - join type: JOIN 类型(INNER、LEFT OUTER、RIGHT OUTER、FULL OUTER、CROSS、SINGLE 或 MARK)。 - - build keys: 构建端用于构建哈希表的表达式。 - - probe keys: 探测端用于从哈希表中读取数据的表达式。 - - filters: 非等值 JOIN 条件,例如 `t.a > t1.a`。 -* **Exchange**: 在 Databend 查询节点之间交换数据,以进行分布式并行计算。 - - exchange type: 数据重分区类型(Hash、Broadcast 或 Merge)。 \ No newline at end of file