SonnetDB 多条件过滤:标签、时间与剩余谓词
SonnetDB 的时序查询可以用WHERE组合标签、时间和字段条件。理解哪些条件可以下推、哪些需要逐点求值,比调整条件在 SQL 中的书写顺序更有用。本文以已有cpumeasurement 为例;示例假定host、region是 TAG,usage是数值 FIELD,throttled是 BOOL FIELD。
先限定标签和时间
SELECTtime,host,region,usageFROMcpuWHEREhost='server-01'ANDregion='cn-hz'ANDtime>=1713657600000ANDtime<1713657900000;这些条件必须同时满足。Unix 时间戳采用毫秒;>=与<表示左闭右开的窗口,相邻窗口共用边界时不会重复包含边界点。
当前WhereClauseDecomposer会展开顶层 AND,把标签等值条件收集到过滤集合,把可下推的时间比较转换为时间窗口。SelectExecutor再按标签匹配 series,并沿查询路径读取相应时间范围。把host写在第一行并不是启用某个索引的开关,不能据此承诺性能提升。
字段条件与 OR 是剩余谓词
SELECTtime,host,usage,throttledFROMcpuWHEREhost='server-01'ANDtime>=1713657600000ANDtime<1713657900000ANDusage>0.7ANDthrottled=TRUE;SELECTtime,host,usageFROMcpuWHEREregion='cn-hz'ANDtime>=1713657600000ANDtime<1713657900000AND(host='server-01'ORhost='server-03');当前源码已把字段比较、非等值标签比较、OR、NOT、IN 等不能下推的条件保留为剩余谓词,供扫描路径逐点求值。支持表达式不意味着全部条件都有索引访问路径;OR 分支里的标签条件也不能简单当作顶层 AND 的标签等值集合。
SQL 谓词采用三值逻辑,NULL 可能产生 UNKNOWN,WHERE 只保留明确为 TRUE 的记录。IN与NOT IN的常量列表已是实际表达式能力,不应把用 OR 写出的例子称作 IN 语法示例。本篇只解释已有查询路径,不把它推广为所有模型、所有组合表达式或生产性能的验收结论。
先观察计划和数据,再决定优化
EXPLAINSELECTusageFROMcpuWHEREhost='server-01'ANDtime>=1713657600000ANDtime<1713657900000;EXPLAIN用于查看扫描范围等估算信息,不能替代真实执行时间和资源测量。为查询加上业务上合理的时间窗口有助于控制读取范围,但时间条件不是 SQL 的强制语法要求;需要全历史数据时,应明确评估数据量与执行预算。
对于删除,先使用相同的标签与时间范围查询检查目标数据。SELECT 的剩余谓词能力不能直接推广成 DELETE 的完整合同;DELETE 的底层墓碑、后续查询过滤和 compaction 行为需要单独核对。本文没有执行删除、SQL 实验或生产性能测试。
资料与代码:SonnetDB 仓库。本文依据当前 SQL 参考和查询分解源码核对,示例需结合实际 schema 与使用版本验证。