仅日期范围扫描 Cassandra CQL 时间戳
Only date range scanning Cassandra CQL timestamp
我有一个 table 如下所示。
CREATE TEST(
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY(HOURLYTIME,FULLTIME)
)
我插入了记录(2014-12-12 00:00:00,2014-12-12 00:00:01,'Hello World')
我想根据每小时保留一次的 HOURLYTIME 字段中的日期时间范围进行搜索 records.When 我尝试使用 token() like
select * from TEST where token(HOURLYTIME)=token('2014-12-12')
要获取该日期的所有记录,它 returns 仅为一个小时的记录,即
2014-12-12 **00:00:00**
如果我添加日期范围
select * from TEST where token(HOURLYTIME)>=token('2014-12-12') AND token(HOURLYTIME)<=token('2014-12-14');
它给出了错误:为起始边界找到了不止一个限制。
如何解决这个问题。
我可以使用 FULLTIME 进行扫描,但我需要提供 ALLOW FILTERING,这将扫描整个记录且效率低下。
日期范围查询工作正常。我正在使用以下版本
[cqlsh 4.1.0 | Cassandra 2.0.4 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
旧版本可能有问题。请检查。
如果没有通过 allow filtering 明确要求,您不能通过范围限制主键。这可以防止需要完整 table 扫描的查询,正如您所注意到的那样很慢并且不会针对真正的大数据大小进行扩展。这样做的原因是主键值是随机散列的,因此指定主键值的范围基本上与提供两个松散耦合的随机数相同。例如,在您的情况下,日期很可能不是单调散列的。这意味着您希望日期的哈希值小于另一个值的哈希值 return 一组完全随机的数据。
这里的问题是您的 table 设置不允许您实际想要执行的查询。您需要为您的 table 建模,以便可以从单个分区中获取您想要的信息。
要进行范围查询,您需要将此列作为聚类列。
在这种情况下会很高效,因为聚类列是按顺序存储的。如果要查找数据,需要指定partition key。
举个例子,我使用 device_id 作为分区键:
CREATE TABLE IF NOT EXISTS mykeyspace.device_data (
DEVICE_ID text,
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY (DEVICE_ID, HOURLYTIME, FULLTIME)
);
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');
-- Effective range query
SELECT * FROM mykeyspace.device_data
WHERE device_id = 'Spam machine'
AND hourlytime > '2014-12-12 00:00:00'
AND hourlytime < '2014-12-12 00:02:00';
或者另一个例子,我按天对数据进行分区(这会很好地跨集群传播数据),并执行范围查询:
CREATE TABLE IF NOT EXISTS mykeyspace.day_data (
DAYTIME timestamp,
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY (DAYTIME, HOURLYTIME, FULLTIME)
);
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');
SELECT * FROM mykeyspace.day_data
WHERE daytime = '2014-12-12'
AND hourlytime > '2014-12-12 00:00:00'
AND hourlytime < '2014-12-12 00:02:00';
上有一篇关于时间序列数据的非常有用的文章
我有一个 table 如下所示。
CREATE TEST(
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY(HOURLYTIME,FULLTIME)
)
我插入了记录(2014-12-12 00:00:00,2014-12-12 00:00:01,'Hello World')
我想根据每小时保留一次的 HOURLYTIME 字段中的日期时间范围进行搜索 records.When 我尝试使用 token() like
select * from TEST where token(HOURLYTIME)=token('2014-12-12')
要获取该日期的所有记录,它 returns 仅为一个小时的记录,即
2014-12-12 **00:00:00**
如果我添加日期范围
select * from TEST where token(HOURLYTIME)>=token('2014-12-12') AND token(HOURLYTIME)<=token('2014-12-14');
它给出了错误:为起始边界找到了不止一个限制。
如何解决这个问题。
我可以使用 FULLTIME 进行扫描,但我需要提供 ALLOW FILTERING,这将扫描整个记录且效率低下。
日期范围查询工作正常。我正在使用以下版本
[cqlsh 4.1.0 | Cassandra 2.0.4 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
旧版本可能有问题。请检查。
如果没有通过 allow filtering 明确要求,您不能通过范围限制主键。这可以防止需要完整 table 扫描的查询,正如您所注意到的那样很慢并且不会针对真正的大数据大小进行扩展。这样做的原因是主键值是随机散列的,因此指定主键值的范围基本上与提供两个松散耦合的随机数相同。例如,在您的情况下,日期很可能不是单调散列的。这意味着您希望日期的哈希值小于另一个值的哈希值 return 一组完全随机的数据。
这里的问题是您的 table 设置不允许您实际想要执行的查询。您需要为您的 table 建模,以便可以从单个分区中获取您想要的信息。
要进行范围查询,您需要将此列作为聚类列。
在这种情况下会很高效,因为聚类列是按顺序存储的。如果要查找数据,需要指定partition key。
举个例子,我使用 device_id 作为分区键:
CREATE TABLE IF NOT EXISTS mykeyspace.device_data (
DEVICE_ID text,
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY (DEVICE_ID, HOURLYTIME, FULLTIME)
);
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');
INSERT INTO mykeyspace.device_data (device_id, hourlytime, fulltime, data)
values('Spam machine', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');
-- Effective range query
SELECT * FROM mykeyspace.device_data
WHERE device_id = 'Spam machine'
AND hourlytime > '2014-12-12 00:00:00'
AND hourlytime < '2014-12-12 00:02:00';
或者另一个例子,我按天对数据进行分区(这会很好地跨集群传播数据),并执行范围查询:
CREATE TABLE IF NOT EXISTS mykeyspace.day_data (
DAYTIME timestamp,
HOURLYTIME TIMESTAMP,
FULLTIME TIMESTAMP,
DATA TEXT,
PRIMARY KEY (DAYTIME, HOURLYTIME, FULLTIME)
);
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:01:00','2014-12-12 00:00:01','Hello World1');
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:02:00','2014-12-12 00:00:02','Hello World2');
INSERT INTO mykeyspace.day_data (DAYTIME, hourlytime, fulltime, data)
values('2014-12-12', '2014-12-12 00:03:00','2014-12-12 00:00:03','Hello World3');
SELECT * FROM mykeyspace.day_data
WHERE daytime = '2014-12-12'
AND hourlytime > '2014-12-12 00:00:00'
AND hourlytime < '2014-12-12 00:02:00';
上有一篇关于时间序列数据的非常有用的文章