- 向量数据库
- 数据库
- 人工智能
- 后端
【免费下载链接】lancedb
Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.
导读
AnalyzePlanDistributedMetrics是 LanceDB 官方 JavaScript SDK(@lancedb/lancedb)中用于控制analyzePlan()输出的类型别名,它决定了在远程分布式查询场景下,执行计划中各个 worker 的运行指标以何种方式展示。本文围绕该类型别名的三个取值("aggregate"、"per_worker"、"full"),结合 SDK 的类型定义、N-API 桥接层与 Rust 核心实现,讲解其语义、默认行为、底层调用链与实战用法,帮助你在排查分布式查询性能问题时快速获得正确的计划视图。
类型别名的定义
该类型别名定义在 SDK 源码 nodejs/lancedb/query.ts:
export type AnalyzePlanDistributedMetrics = "aggregate" | "per_worker" | "full";并在包级入口 nodejs/lancedb/index.ts 中公开导出,因此在 TypeScript / JavaScript 项目中可以通过如下方式引入:
import * as lancedb from "@lancedb/lancedb"; import type { AnalyzePlanDistributedMetrics } from "@lancedb/lancedb";它只允许三个字面量字符串,作用是为QueryBase.analyzePlan()方法提供类型安全的选择约束——传入这三个取值之外的值会在类型检查阶段直接报错。
三个取值的语义
该类型别名的三个取值在 Rust 核心中对应三个枚举变体,其权威语义注释见 rust/lancedb/src/query.rs:
| 类型取值 | Rust 枚举变体 | 语义 |
|---|---|---|
"aggregate" | AnalyzePlanDistributedMetrics::Aggregate(默认) | 将各分布式 worker 的指标聚合成一棵合成的执行计划树输出,保留历史遗留的展示格式 |
"per_worker" | AnalyzePlanDistributedMetrics::PerWorker | 为每一个分布式 worker 各渲染一棵原始的 worker 侧计划树,便于逐节点定位问题 |
"full" | AnalyzePlanDistributedMetrics::Full | 先输出聚合树,再依次输出各 worker 的原始树,兼顾整体概览与细节排查 |
从源码结构可以推断,"full"是"aggregate"与"per_worker"两种输出的叠加组合,适用于既想快速了解整体聚合情况、又需要深入单 worker 明细的调试场景。
使用位置:analyzePlan() 方法
AnalyzePlanDistributedMetrics是analyzePlan()方法的可选参数类型,方法定义见 nodejs/lancedb/query.ts:
async analyzePlan( distributedMetrics?: AnalyzePlanDistributedMetrics, ): Promise<string> { const distributedMetricsMode = distributedMetrics ?? "aggregate"; const inner = await this.getInner(); return inner.analyzePlan(distributedMetricsMode); }关键行为要点:
- 参数可选,默认
"aggregate":未传参时,SDK 自动回退到"aggregate"(见 nodejs/lancedb/query.ts),与 Rust 侧的默认值保持一致(QueryExecutionOptions::default()中analyze_plan_distributed_metrics默认即Aggregate,见 rust/lancedb/src/query.rs); - 返回字符串:
analyzePlan()返回的是带运行时指标的查询执行计划文本,每个执行步骤会内联output_rows、elapsed_compute、bytes_read、iops、requests等指标; - 调用链:TS 层 → N-API 原生方法(nodejs/src/query.rs)→ Rust 核心
analyze_plan_with_options。
底层调用链:从字符串到查询参数
TS 层的字符串值最终要传给 Rust 核心,二者之间的转换由 N-API 桥接函数完成,见 nodejs/src/query.rs:
fn analyze_plan_options( distributed_metrics: Option<String>, ) -> napi::Result<QueryExecutionOptions> { let analyze_plan_distributed_metrics = match distributed_metrics.as_deref().unwrap_or("aggregate") { "aggregate" => AnalyzePlanDistributedMetrics::Aggregate, "per_worker" => AnalyzePlanDistributedMetrics::PerWorker, "full" => AnalyzePlanDistributedMetrics::Full, mode => { return Err(napi::Error::from_reason(format!( "Invalid distributedMetrics value '{}'. Expected one of: \ 'aggregate', 'per_worker', 'full'", mode ))); } }; // ... }从这段实现可以确认两点:
- 运行时同样校验取值:即使绕过 TypeScript 类型检查(例如通过动态字符串调用),传入非法值也会在原生层抛出
Invalid distributedMetrics value ...错误,三个合法值恰好与类型别名的三个字面量一一对应; - 字符串映射有迹可循:Rust 枚举通过
as_query_param()方法将变体序列化为查询参数值(见 rust/lancedb/src/query.rs),Aggregate → "aggregate"、PerWorker → "per_worker"、Full → "full",与 TS 类型别名完全对称。
远程分布式计划的实际请求行为
该参数仅影响远程分布式查询计划。Rust 核心在QueryExecutionOptions的字段注释中明确说明(见 rust/lancedb/src/query.rs):该选项只影响ExecutableQuery::analyze_plan对远程分布式查询计划的展示,本地查询执行会忽略此选项。
在远程表实现 rust/lancedb/src/remote/table.rs 中,该选项被转换为 HTTP 请求的查询参数:
let mut request = self .client .post(&format!("/v1/table/{}/analyze_plan/", self.identifier)); if options.analyze_plan_distributed_metrics != AnalyzePlanDistributedMetrics::Aggregate { request = request.query(&[( "distributed_metrics", options.analyze_plan_distributed_metrics.as_query_param(), )]); }值得注意的细节:
- 请求路径为
POST /v1/table/{table}/analyze_plan/,请求体携带查询定义; "aggregate"(默认)时不附加任何查询参数,服务端按默认聚合模式处理;只有显式选择"per_worker"或"full"时才追加?distributed_metrics=per_worker或?distributed_metrics=full;- 这一行为有测试用例佐证:在 rust/lancedb/src/remote/table.rs 的测试中,传入
AnalyzePlanDistributedMetrics::PerWorker后,断言请求 URL 携带了("distributed_metrics", "per_worker")查询对。
实战示例
基础用法:查看带指标的执行计划
import * as lancedb from "@lancedb/lancedb"; const db = await lancedb.connect("./.lancedb"); const table = await db.createTable("my_table", [ { vector: [1.1, 0.9], id: "1" }, ]); // 默认以 "aggregate" 模式输出(本地查询不受该参数影响) const plan = await table.query().nearestTo([0.5, 0.2]).analyzePlan(); console.log(plan);本地执行时输出的计划形如(摘自 nodejs/lancedb/query.ts 的文档示例):
AnalyzeExec verbose=true, metrics=[] ProjectionExec: expr=[id@3 as id, vector@0 as vector, _distance@2 as _distance], metrics=[output_rows=1, elapsed_compute=3.292µs] Take: columns="vector, _rowid, _distance, (id)", metrics=[output_rows=1, elapsed_compute=66.001µs, batches_processed=1, bytes_read=8, iops=1, requests=1] CoalesceBatchesExec: target_batch_size=1024, metrics=[output_rows=1, elapsed_compute=3.333µs] GlobalLimitExec: skip=0, fetch=10, metrics=[output_rows=1, elapsed_compute=167ns] FilterExec: _distance@2 IS NOT NULL, metrics=[output_rows=1, elapsed_compute=8.542µs] SortExec: TopK(fetch=10), expr=[_distance@2 ASC NULLS LAST], metrics=[output_rows=1, elapsed_compute=63.25µs, row_replacements=1] KNNVectorDistance: metric=l2, metrics=[output_rows=1, elapsed_compute=114.333µs, output_batches=1] LanceScan: uri=/path/to/data, projection=[vector], row_id=true, row_addr=false, ordered=false, metrics=[output_rows=1, elapsed_compute=103.626µs, bytes_read=549, iops=2, requests=2]远程分布式查询:选择指标展示模式
import * as lancedb from "@lancedb/lancedb"; // 连接远程(分布式)LanceDB 表 const db = await lancedb.connect({ uri: "db://your-remote-endpoint" }); const table = await db.openTable("my_table"); // 方式一:仅查看聚合后的单棵计划树(默认行为,可省略参数) const aggregatePlan = await table.query().nearestTo([0.5, 0.2]).analyzePlan("aggregate"); // 方式二:逐 worker 查看原始计划树,定位单个节点的问题 const perWorkerPlan = await table.query().nearestTo([0.5, 0.2]).analyzePlan("per_worker"); // 方式三:聚合树 + 各 worker 原始树一起输出,兼顾全局与细节 const fullPlan = await table.query().nearestTo([0.5, 0.2]).analyzePlan("full");配合类型使用,保证编译期正确性
import type { AnalyzePlanDistributedMetrics } from "@lancedb/lancedb"; // 以受约束的类型封装"可配置的展示模式" function buildAnalyzer(mode: AnalyzePlanDistributedMetrics) { return async (table: lancedb.Table) => { const plan = await table.query().nearestTo([0.5, 0.2]).analyzePlan(mode); return plan; }; } // 编译期通过 const analyzer = buildAnalyzer("per_worker"); // 编译期报错:TS2345,Argument of type '"worker"' is not assignable to parameter of type 'AnalyzePlanDistributedMetrics' // buildAnalyzer("worker");使用注意事项
- 仅对远程分布式查询生效:本地文件表(如
lancedb.connect("./.lancedb"))的执行计划是单机单进程执行,distributedMetrics参数会被忽略,无论传哪个值输出结构一致; - 默认值语义:不传参等价于
"aggregate",目的是保留既有(legacy)输出格式;若你依赖旧的聚合计划文本做解析,升级 SDK 后无需改动代码; - 三个取值是互斥的选择,
"full"不是聚合级别更高的"超集配置",而是聚合树与逐 worker 树的顺序拼接,输出文本更长,适合诊断而非日常巡检; - 取值受运行时二次校验:即便绕过类型检查传入非法字符串,原生层也会抛出明确错误,错误信息会列出全部合法取值(见 nodejs/src/query.rs)。
相关源码参考
- 类型别名定义与
analyzePlan()方法:nodejs/lancedb/query.ts、nodejs/lancedb/query.ts - 包级导出:nodejs/lancedb/index.ts
- N-API 桥接与取值校验:nodejs/src/query.rs
- Rust 枚举定义与默认值:rust/lancedb/src/query.rs、rust/lancedb/src/query.rs
- 远程请求参数构造与测试佐证:rust/lancedb/src/remote/table.rs、rust/lancedb/src/remote/table.rs
- 向量数据库
- 数据库
- 人工智能
- 后端
【免费下载链接】lancedb
Developer-friendly OSS embedded retrieval library for multimodal AI. Search More; Manage Less.
相关推荐
TiDB执行计划:解读分布式查询计划
TiDB执行计划:解读分布式查询计划 引言:分布式数据库的查询优化挑战 你是否曾在分布式环境中遇到SQL查询性能瓶颈?当数据分散在多个节点,传统单机数据库的查询
数据库分布式数据库后端OLAP从零开始:Unitree RL Gym强化学习机器人控制完整指南
从零开始:Unitree RL Gym强化学习机器人控制完整指南 想要让机器人像真实生物一样灵活运动吗?Unitree RL Gym是一个强大的开源框架,专为U
人工智能强化学习机器人具身智能Dagger TypeScript SDK 的 EngineCacheEntryID 类型别名:引擎缓存条目标识符的 branded string 模式深度解析
Dagger TypeScript SDK 的 EngineCacheEntryID 类型别名:引擎缓存条目标识符的 branded string 模式深度解析
DevOpsCI/CD后端CLI云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考