假设我有这个表
CREATE TABLE device_data_by_year (
year int,
device_id uuid,
sensor_id uuid,
nano_since_epoch bigint,
unit text,
value double,
source text,
username text,
PRIMARY KEY (year, device_id, nano_since_epoch,sensor_id)
) WITH CLUSTERING ORDER BY (device_id desc, nano_since_epoch desc);
我需要查询 2017 年至 2018 年期间特定设备和传感器的数据。在这种情况下,将发出 2 个查询:
select * from device_data_by_year where year = 2018 AND device_id = ? AND sensor_id = ? AND nano_since_epoch >= ? AND nano_since_epoch <= ?
select * from device_data_by_year where year = 2018 AND device_id = ? AND sensor_id = ? AND nano_since_epoch >= ? AND nano_since_epoch <= ?
目前,我循环访问结果集并构建包含所有结果的列表。我知道这有一天可能会(并且会(遇到 OOM 问题。有没有更好的方法,如何处理/合并查询结果到一个集合中?
谢谢
您可以使用IN
来指定年份列表,但这不是很理想的解决方案 - 因为year
字段是分区键,那么数据很可能在不同的机器上,所以其中一个节点将作为"协调器"工作,并且需要向另一台机器询问结果,并聚合数据。从性能的角度来看,并行发出的 2 个异步请求可能会更快,然后在客户端进行合并。
附言您的数据模型存在非常严重的问题 - 您按年份划分,这意味着:
- 数据在集群中的分布不是很好 - 只有 N=RF 机器会保存数据;
- 即使您只有数百个设备,这些分区也将非常大,每分钟报告一次测量;
- 只有一个分区是"热"的 - 它将接收一年中的所有数据,其他分区不会经常使用。
您可以使用数月甚至数天作为分区键来减小分区大小,但它仍然无法解决"热"分区的问题。
如果我没记错的话,DataStax学院的数据建模课程有一个传感器网络数据模型的例子。
将表结构更改为:
CREATE TABLE device_data (
week_first_day timestamp,
device_id uuid,
sensor_id uuid,
nano_since_epoch bigint,
unit text,
value double,
source text,
username text,
PRIMARY KEY ((week_first_day, device_id), nano_since_epoch, sensor_id)
) WITH CLUSTERING ORDER BY (nano_since_epoch desc, sensor_id desc);
根据@AlexOtt提议。需要对应用程序逻辑进行一些更改 - 例如,findAllByYear现在需要在一周内迭代。
回到最初的问题:您是否愿意发送 52 个查询(getDataByYear,每周一个查询(还是在这里使用 IN 运算符?