优化 ThingsDB:通过类型索引提升速度
Source: Dev.to
“理想”方式:层级访问
在 ThingsDB 中,访问数据的首选模式是通过你自己的代码逻辑。在 InfraSonar ,我们对 Container 类型使用层级结构。每个容器都可以有子容器,我们从 .root 容器开始检索整棵树。
new_type('Container');
set_type('Container', {
name: 'str',
children: '{Container}',
get_containers: |this| {
// Recursively collect all containers in a set
this.children.reduce(|a, c| a |= c.get_containers(), set(this));
}
});
// Return a set with all containers via the root:
.root.get_containers();
问题:type_all() 速度慢
在某些情况下,数据并不容易通过单一根节点访问,或者你仅仅需要一个平铺的、包含某类型所有实例的列表。为此,ThingsDB 提供了 type_all()。
历史上,type_all() 设计用于调试和一次性迁移,而不是高频率的生产代码。它内部会执行完整扫描——遍历集合中的每个对象,筛选出匹配请求类型的对象。
如果你测量性能,差异是显而易见的:
// Returns an object with `data` (the set) and `time` (execution duration)
timeit(type_all('Container'));
解决方案:启用类型索引
现在你可以让 ThingsDB 为特定类型维护专用索引。这把工作量从 查询时 转移到 存储时,使检索速度极快。
在已有类型上启用索引:
// Enable the 'idx' flag on the Container type
mod_type('Container', 'idx', true);
或者在创建时直接使用 IDX 标志:
new_type('Container', IDX);
性能影响
一旦建立索引,运行 type_all('Container') 就不再需要完整扫描。ThingsDB 只需返回预先填充好的实例集合。
注意: 你可能需要执行两次查询才能看到完整效果。ThingsDB 是“惰性”的,通常会在标志启用后第一次请求时开始构建索引。
总结
虽然遍历你自己的数据结构(比如我们的 .root 示例)仍然是最 “ThingsDB‑原生” 的做法,但新的 IDX 标志让 type_all() 成为生产工具集中可行且高性能的工具。