目前,我们有以下表格,可让我们根据日期执行查询。
CREATE TABLE events_by_day(
...
traffic_type text,
device_class text,
country text,
...
yyyymmdd text,
event_type text,
the_datetime timeuuid,
PRIMARY KEY((yyyymmdd, event_type), the_datetime));
create index index_country on events (country);
create index index_traffic_type on events (traffic_type);
create index index_device_class on events (device_class);
支持以下查询。
select * from events where yymmdd = '20160303' and event_type in ('view');
select * from events where yymmdd = '20160303' and event_type in ('lead', 'view', 'sales');
select * from events where yymmdd = '20160303' and event_type = 'lead' and country = 'my' and device_class = 'smart' and traffic_type = 'WEB' ALLOW FILTERING;
当我们需要一天以上的数据时,我们会多次执行查询。说,我需要从2016年3月1日到2016年3月3日“查看”数据,我会查询3次。
select * from events where yymmdd = '20160301' and event_type in ('view');
select * from events where yymmdd = '20160302' and event_type in ('view');
select * from events where yymmdd = '20160303' and event_type in ('view');
目前,所有这些都符合我们的要求。
然而,在未来,假设我们有新要求,我们需要从2013年到2016年“查看”数据。
不是查询它1460次(365天* 4年),我们通常会创建一个像
这样的全新空表。CREATE TABLE events_by_year(
...
traffic_type text,
device_class text,
country text,
...
yyyy text,
event_type text,
the_datetime timeuuid,
PRIMARY KEY((yyyy, event_type), the_datetime));
然后使用events_by_day
中的大数据填充数据(由于events_by_day
表已有多行,可能需要几天才能完成插入)?
答案 0 :(得分:2)
简短的回答是肯定的。通常将每周,每月,每年的数据汇总到新表中,以便可以更有效地查询它。
例如,最好保持每天运行的滚动聚合(可能是另一个合适的时间段,具体取决于您的数据和要求)并计算这些值,而不是等到需要它们然后运行过程需要几天时间。
答案 1 :(得分:1)
我们创建一个全新的空表是一种常见的做法吗?
是的。这被称为"基于查询的建模,"这在卡桑德拉很常见。虽然Cassandra可以扩展并且性能良好,但它在查询灵活性方面并没有提供太多帮助。因此,要解决这个问题,而不是使用执行不良的方法(二级索引,允许过滤)来查询现有表,该表通常与不同的PRIMARY KEY重复。基本上,您正在交换磁盘空间以提高性能。
不要自我推销或任何事情,但我在上一次Cassandra峰会上就这个主题发表了演讲。您可能会发现这些幻灯片很有用:Escaping Disco Era Data Modeling
说到性能,已经证明在分区键上使用IN
关键字与使用二级索引一样糟糕。通过3个并行查询,您可以获得更好的性能,而不是:event_type in ('lead', 'view', 'sales')
。
此外,您的上一次查询是使用ALLOW FILTERING
,这是您在生产系统上永远不应该做的事情,因为它会导致扫描整个表格和几个节点。
为获得理想的性能,最好确保查询以特定数据分区为目标。这样,您只会访问单个节点,而不会将无关的网络流量引入等式中。