Crate:为什么要求PRIMARY KEY列出现在PARTITIONED BY子句中?

时间:2017-01-12 16:58:22

标签: crate

你可以帮我理解我在这篇文章中读到的内容吗? https://crate.io/docs/reference/sql/partitioned_tables.html

在这些示例表中,列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查找命中每个分区,还是确切知道要去哪里?如果我只运行一个仅限于今天的聚合查询,它会点击每个分区还是仅保存今天的数据?

1 个答案:

答案 0 :(得分:1)

这是一个很好的问题!由于分区是排序的“子表”,这有助于减少查询数据的大小。

主键影响CrateDB中的routing,因此将其添加到分区表(需要更广泛的路由)将拒绝partitioned by clause中的任何非主键列。因此,您的选择如下:

  • a)虽然这样做无法有效地进行PK查找,但这似乎是一个明智的选择 - 使用fulltext index可以加速常规字符串查找 - 但它也会删除read-after -write-consistent主键查找添加。根据您生成主键的方式,可能可以使用内部_id列(用于查找),或在id-lookup之前发出REFRESH TABLE
  • b)会产生与主键一样多的分区(因为它们是唯一的......) - 所以这个选项会创建太多的分区

由于选项b)会导致混乱,我建议选项a)。但是,如果主键查找对您的应用程序至关重要,并且预期的数据量不是那么大(几百万个很好 - 当然取决于簇大小和机器规格),它可能在没有分区的情况下工作正常! / p>

干杯,克劳斯