我有一点设计问题,我有以下要求:
SELECT MAX(idt) FROM table WHERE idt < 2018
但我无法弄清楚如何根据此请求创建表。 idt 必须是一个群集密钥才能执行大于或低于的操作以及最大程度的混合但我不知道我应该使用什么作为分区键(我不想使用ALLOW FILTERING)。 我发现的唯一解决方案是使用常量值作为分区键,但我知道它被认为是一个糟糕的设计。 有什么帮助吗?
谢谢,
答案 0 :(得分:0)
您需要以某种方式对数据进行分区。如果不这样,就像你说的那样,要么从整个集群中读取所有内容(允许过滤),要么将所有内容都放在一个分区中(常量键)。对数据,设计或目标一无所知,常见的设置是按日期分区,如:
SELECT id FROM table WHERE bucket = '2018' AND id < 100 limit 1;
然后你的密钥看起来像((bucket), id)
排序ID DESC在分区头部最大。在这种情况下,桶是按年份,因此最终每年都会查询您的查询。如果idt不是唯一的,你可能需要做类似的事情:
((uuid), idt)
或((bucket), uuid, idt)
按idt DESC排序(如果该记录不是唯一的,则再次发出)。然后你可以做像
SELECT max(idt) FROM table WHERE GROUP BY bucket
虽然还是更好
SELECT max(idt) FROM table WHERE bucket = '2018' GROUP BY bucket
这将为您提供每个桶的最大值,因此您必须通过它进行翻页并自己生成全局最大值,但对于群集来说它更好,因为它会自然地限制一点点与单个查询关闭整个群集。可能在该查询上也是个好主意,也可以将获取大小限制为10或100或者与默认值5000相比,因此结果集页面更慢(防止协调器上的工作太多)。
要让所有这些工作在其他地方完成,你可能会考虑使用Spark,因为它可以为您提供更多丰富的查询并尽可能高效地执行(这可能效率不高但会尝试)。