SonnetDB Graph Beta 查询:SQL/PGQ、受限 GQL 风格与 EXPLAIN

SonnetDB Graph Beta 查询:SQL/PGQ、受限 GQL 风格与 EXPLAIN

SonnetDB 的原生属性图目前是 Graph Beta;本文介绍如何用 SQL/PGQ GRAPH_TABLE 与嵌入式受限 GQL 风格查询一跳或有界路径,并用 EXPLAIN 检查实际访问路径、预算和拒绝边界。

SonnetDB Graph Beta 查询:SQL/PGQ、受限 GQL 风格与 EXPLAIN

AI 主题示意图,并非实测截图。

本文按本地源码提交 dbc8178988a0293ed67d24e6f70b78b970465aa0 和 Graph 专题合同核对。GitHub 当前正式 Release 是 v4.0.0,但本文所述较新的 Graph Beta 合同应先按源码提交、目标包与实际 Server 分别核验,不能从本文或本地回归推断已在所有发行物、远程服务或固定硬件上验收。

1. 先选对入口

Graph Beta 有两个查询写法,但它们不是两套不同的存储或权限通道:

入口 适合的场景 关键限制
SQL/PGQ GRAPH_TABLE Server、HTTP、ADO.NET、Studio 和连接器 继续使用既有 SQL 数据面和权限边界
SqlExecutor.ExecuteGql 显式 opt-in 的嵌入式 .NET 调用 不是新的 wire endpoint,也不是 DDL/DML 通道
EXPLAIN [ANALYZE] 复核计划、统计新鲜度与运行计数 普通 EXPLAIN 不为估算扫描业务数据

受限 GQL 风格入口会解析为既有 SelectStatement 和 GraphTableSource,再走与 SQL/PGQ 相同的成本规划、原生 adjacency 或关系映射 accessor、预算和执行器。因此,同一个 MATCH 不应通过字符串拼接在两条线路上制造不同的安全或结果语义。

2. 从 SQL/PGQ 开始写一跳查询

关系映射图可以使用 catalog 中声明的 label 名;原生图使用正整数 label ID。请在隔离的示例数据库中逐条执行以下建图与写入语句;它们会写数据,不要对已有同名业务图重复运行。

CREATE GRAPH topology;
INSERT INTO GRAPH topology VERTEX (id, labels, property_7)
VALUES (42, 1, 'pump'), (43, 1, 'valve');
INSERT INTO GRAPH topology EDGE (id, source_id, target_id, label_id)
VALUES (100, 42, 43, 2);

下面把 @anchor 绑定为 Int64 值 42,取得一跳关系的稳定输出名;预期一行是 42, 43, 100。支持参数的调用方式见下一节,纯 SQL 控制台也可在这个固定示例中将参数写成字面量 42。

SELECT source_id, target_id, edge_id
FROM GRAPH_TABLE (
    topology
    MATCH (a IS 1)-[e IS 2]->(b IS 1)
    WHERE a.id = @anchor
    COLUMNS (a.id AS source_id, b.id AS target_id, e.id AS edge_id)
)
ORDER BY edge_id
LIMIT 10;

这个例子表达的是一个 pattern、两个 vertex 变量和一个 edge 变量。固定一跳可省略 hop 范围;可变路径必须满足 1 <= min <= max <= 64。方向还可写为入向或无向模式,但不要把这一有限语法误解为完整 Cypher 或 ISO GQL。

查询前请先明确结果预算和读者真正需要的列。LIMIT 约束的是返回结果,不会自动证明整个执行链路在任意负载下流式、无界内存或具备生产容量。原生图和关系映射图都可能使用索引 seek 或有界 scan fallback;应以计划输出而不是名称猜测为准。

3. 嵌入式 GQL 风格入口如何等价执行

嵌入式程序可用 SqlParameters 传入参数,再显式调用 ExecuteGql。下面的 USE GRAPH 写法与上一节 SQL/PGQ 查询生成相同的 Graph AST、计划和结果;它没有绕过 SQL 参数绑定。

using SonnetDB.Engine;
using SonnetDB.Sql;
using SonnetDB.Sql.Execution;

// 此目录须是已按上一节创建示例图的独立数据库目录。
using var db = Tsdb.Open(new TsdbOptions { RootDirectory = @"D:\sonnetdb-examples\graph-query" });

var parameters = new SqlParameters().AddNamed("anchor", 42L);

SelectExecutionResult result = SqlExecutor.ExecuteGql(
    db,
    """
    USE GRAPH topology
    MATCH (a IS 1)-[e IS 2]->(b IS 1)
    WHERE a.id = @anchor
    RETURN a.id AS source_id, b.id AS target_id, e.id AS edge_id
    ORDER BY edge_id
    LIMIT 10
    """,
    parameters);

GqlParser.Parse 可单独返回现有 SQL typed AST。EXPLAIN 或 EXPLAIN ANALYZE 应放在 USE GRAPH 前,返回的字段仍与等价 GRAPH_TABLE 查询相同,而不是新增一个只对 GQL 生效的计划格式。

4. 用 EXPLAIN 验证访问策略,而不是猜测性能

Graph SQL V1 为每个 label 和每个非空 property 维护自动等值派生索引。对于形如 variable.property_<id> = scalar 的谓词,graph_cost_v1 会比较两侧 value cardinality,并编译为已有的 property seek;没有统计时仍可使用该索引,但估算是有界启发式。非等值或不支持的谓词会回退 label index 并保留残余过滤。

可从计划中查看以下信息:

EXPLAIN ANALYZE
SELECT source_id, target_id
FROM GRAPH_TABLE (
    topology
    MATCH (a IS 1)-[e IS 2]->(b IS 1)
    WHERE a.property_7 = 'pump'
    COLUMNS (a.id AS source_id, b.id AS target_id)
);

计划会报告 anchor_side、anchor_access_path、anchor_property_id、statistics_sequence、statistics_freshness、estimate_source、edge_access_path 和 fallback_reason。使用 ANALYZE 后还会给出实际 anchor 路径、rows、expansions、frontier 与 elapsed。属性 seek 后仍执行完整 MATCH 谓词,所以优化只能改变候选获取方式,不能改变查询语义。

ANALYZE GRAPH <name> 的统计属于可重建内存状态:重开后是 missing,后续写入会使它变为 stale。因此“有索引”不等于“统计永远新鲜”,更不等于固定硬件上的吞吐或延迟承诺。

5. 明确会被拒绝的形状

当前受限入口有意拒绝以下写法或能力:

  • RETURN *、重名输出而没有 AS 别名、多语句输入;
  • 多 pattern、OPTIONAL MATCH、UNION、GROUP BY;
  • Cypher 的 :Label、MERGE、WITH、UNWIND、CALL;
  • GQL DDL/DML、完整 ISO GQL、Bolt 与分布式图协议;
  • 把 CREATE/DROP PROPERTY INDEX 当作 V1 的命名或范围/复合/partial 索引接口。

图的创建和 mutation 仍走现有 Graph API 或 SQL,并遵守原有权限与乐观版本合同。Graph SQL V1 的 UPDATE/DELETE 需要且只能用 id 与 element_version 的等值条件;跨 graph/关系表原子事务、无版本 last-write-wins、DETACH DELETE 也不属于本文的支持范围。

6. 交付前检查清单

  1. 对远程、ADO.NET、Studio 或连接器优先写等价 SQL/PGQ GRAPH_TABLE,并使用参数而非拼接用户输入。
  2. 对嵌入式调用才使用显式 ExecuteGql;将 EXPLAIN 的访问路径和 fallback 原因随诊断记录保存。
  3. 将 LIMIT、hop 上限和查询预算当作合同的一部分;超出支持矩阵时拆为已支持的 SQL 派生表,或在应用端显式组合。
  4. 在变更数据后重新审视统计状态;将 missing/stale 写入诊断,而不是把旧估算当作实时事实。

Graph Beta 已有原生邻接、SQL/PGQ、受限嵌入式 GQL 风格入口和自动回归,但固定目标硬件、LDBC/Graphalytics、七天 mixed workload、恢复和发布门禁仍未闭环。本文示例按当前 API 与测试源码静态复核,未在本次写作中实际执行;本文没有运行真实 Server、远程连接、LDBC、固定硬件、容量、长期负载或生产验证。

参考


关注我们,扫码进群沟通

欢迎关注我们,扫码加入微信或 QQ 交流群,一起交流技术实践,分享使用经验和问题反馈。

微信交流二维码

微信交流二维码

QQ 交流群:IoTSharp,群号 63631741

IoTSharp QQ 交流群二维码,群号 63631741

请扫码并关注我们,进群沟通。若二维码暂时无法使用,可通过 QQ 群号 63631741 搜索加入。

posted @ 2026-10-28 03:48  IoTSharp  阅读(6)  评论(0)    收藏  举报