在这些示例表中,列id long
不是primary_key
;实际上,id
不能成为主键,因为如下所述“如果设置了主键,它必须出现在PARTITION BY
子句中”
在我的应用中,我历史上primary key
上有id string NOT NULL
,但现在我想在生成的日期列上添加此表上的分区,就像示例{{1}中一样}。我已经读过日期列上的分区将有助于查询按时间段划分的查询速度(例如,计算今天的所有记录,例如,只能访问今天的分区),并帮助我存档较旧的数据帧(例如,任何> 180)天),但我不想失去单个PK查找的性能。
因为我不能只做partition_date timestamp GENERATED ALWAYS AS date_trunc('day', created_at)
,所以我最好......
a)从PARTITIONED BY (partition_date)
删除主键约束?我很紧张这会影响我单行查找的性能!在这种情况下,PK必须在分区键中才有意义,因为查找id
理想情况下只需要访问单个节点。
或
b)使用两列作为分区键,如WHERE id = "abc-123"
- 这看起来很奇怪,因为本能地,我想假设PARTITIONED BY (id, partition_date)
具有高基数并且对于分区列来说是一个糟糕的选择,'day'或'month'会更好,就像你的文档中的示例所示。在这种情况下,我的PK查找命中每个分区,还是确切知道要去哪里?如果我只运行一个仅限于今天的聚合查询,它会点击每个分区还是仅保存今天的数据?
答案 0 :(得分:1)
这是一个很好的问题!由于分区是排序的“子表”,这有助于减少查询数据的大小。
主键影响CrateDB中的routing,因此将其添加到分区表(需要更广泛的路由)将拒绝partitioned by clause中的任何非主键列。因此,您的选择如下:
_id
列(用于查找),或在id-lookup之前发出REFRESH TABLE
。由于选项b)会导致混乱,我建议选项a)。但是,如果主键查找对您的应用程序至关重要,并且预期的数据量不是那么大(几百万个很好 - 当然取决于簇大小和机器规格),它可能在没有分区的情况下工作正常! / p>
干杯,克劳斯