2

您能帮我理解我在本文档中阅读的内容吗? https://crate.io/docs/reference/sql/partitioned_tables.html

在这些示例表中,列id long不是primary_key; 实际上,id这里不能是主键,因为如下所述“如果设置了主键,则它必须存在于PARTITION BY子句中”

在我的应用程序中,我历来有一个primary keyon id string NOT NULL,但现在我想在这个表上添加分区,在生成的日期列上,就像在示例中一样partition_date timestamp GENERATED ALWAYS AS date_trunc('day', created_at)。我已经读过,对日期列进行分区将有助于提高按时间段范围内的查询速度(例如,计算今天的所有记录,只会命中今天的分区),并帮助我归档较旧的数据帧(例如 > 180 天的任何数据) ),但我不想失去单 PK 查找的性能。

所以,既然我做不到PARTITIONED BY (partition_date),我最好……

a) 删除主键约束id?我很紧张这会影响我的单行查找性能!在这种情况下,PK 必须在分区键中是有意义的,因为理想情况下查找WHERE id = "abc-123"应该只需要命中单个节点。

或者

b) 使用两列作为分区键,比如PARTITIONED BY (id, partition_date)-- 这看起来很奇怪,因为本能地,我想假设它id具有高基数并且对于分区列来说是一个糟糕的选择,而“日”或“月”会更好,如您的文档中的示例所示。在这种情况下,我的 PK 查找是否命中了每个分区,或者它是否确切地知道要去哪里?如果我运行仅限于今天的聚合查询,它会命中每个分区还是只命中保存今天数据的分区?

4

1 回答 1

1

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

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

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

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

干杯,克劳斯

于 2017-01-12T18:18:47.003 回答