范围查询大型 PouchDB 数据集的最佳性能方式

Most performant way of range querying large PouchDB datasets

我正在构建一个每秒收集大量不同指标的物联网应用程序。在客户端上,我使用图表显示数据。

但是,每次我更改 charts/reload 页面的时间范围时,都需要很长时间才能从服务器加载所有数据点。所以我开始研究浏览器中的持久存储,主要使用 PouchDB。然后每次浏览器刷新时,数据获取都会更加快速。当然你必须考虑浏览器配额等,但那是另一个问题。

示例数据点如下所示

{
   "metricId": <String>,
   "metricName": <String>,
   "timestamp": <Unix Timestamp>
   "value": <Integer>
}

方法 1 - 多个数据库,一个索引

由于我有许多不同的指标,我正在考虑为每个指标创建一个新的 PouchDB 数据库,然后在时间戳上建立索引。

// (using pouchdb-find plugin)
const db = new PouchDB(<metricName>);
db.createIndex({ index: { fields: ['timestamp'] } })
db.find({ 
    selector: { timestamp: { '$gte' : from, '$lte' : to }}
})

方法 2 - 一个数据库,多个索引

另一种解决方案是创建一个数据库来保存所有指标,并改为使用多个索引。

// (using pouchdb-find plugin)
const db = new PouchDB('all_data');
db.createIndex({ 
    index: { fields: ['metricId', 'metricName', 'timestamp'] } 
});
db.find({ 
    selector: { 
        $and: [
            { metricId: metricId }, 
            { metricName: metricName },
            { timestamp: { '$gte' : from, '$lte' : to }}
        ]
    }
})

问题

两者哪个性能最好,或者是否有更智能的创建索引的方法?或者是否有完全不使用 PouchDB 的不同方法?

在找到解决方案时回答我自己的问题,不是使用 PouchDB,而是使用 YDN-DB。使用上面的 方法 1 和多个数据库和一个索引列(整数时间戳类型),我已经达到了非常好的性能。

写入和读取 ~5000 行大约需要 300 毫秒。我的测试表明,这种方法比使用复合索引(方法 2)快 3 倍左右。

如果其他人偶然发现了这个 SO 问题,请在此处发布代码。

// Create unique DB with index
const dbname = [metricId, metricName].join("_");
const schema = {
    stores: [{
        name: 'metrics',
        indexes: [{ keyPath: 'timestamp' }]
    }]
}
const db = new ydn.db.Storage(dbname, schema);

// writing data.. timestamp is unix timestamp
db.put('metrics', { timestamp, value }, timestamp);

// reading data
const query = db.from('metrics').where('timestamp', '>=', from, '<=', to);
query.list(5000).done(result => {
    console.log(result);
});