3

我正在设计一个新的实验室数据库。

我的主数据表将至少有id (PK NUMBER)created_on (DATE)。此外,对于任何两个条目,具有较高的条目id将具有较晚的created_on日期。

我计划分区created_on以提高最近输入数据的性能。由于列一起增加,表也将被id隐式分区。Oracle 不会知道隐含的分区,id以利用id.

两个问题:

  1. 如何强制两列一起增加?

  2. 如何利用这种隐式分区进行表连接?

4

5 回答 5

4

在我看来,分区的决定应该更多地基于对表维护活动(清除、归档等)的需要,而不是性能。在您的情况下,我猜您可能会对日期范围的样本执行索引范围扫描,因此请确保日期索引也是本地(而不是全局)分区的。如果您截断分区,这也将消除重建索引的需要。我还猜测 PK 上的连接将使用 rowid 搜索,因此这将在索引范围扫描之后发生,并且分区无法影响这一点。

[编辑]

关于关联 PK 和 CREATED_ON 列,我使用了几个系统,这些系统从以 YYYYMMDD 为前缀的序列构造数字键并且效果很好。你必须:

  • 自由估计您每天将拥有的样本数量

  • 定义一个序列,将其作为最大值,然后循环回 0

  • 有一个返回 YYYYMMDD || 的函数 {sequence value left-padded with
    zeros to the appropriate fixed length} 在需要密钥时从触发器或应用程序代码中调用

有些人不同意在密钥中嵌入含义,但在实践中,查看样本 ID 并了解它的处理时间很有用

于 2009-08-14T15:43:09.587 回答
2

真正重要的问题是:您是否需要按 ID 范围进行查询?您不太可能需要使用ID BETWEEN :A AND :B. 因此,Oracle 不会从相关分区方案中受益。对于所有重要的事情,您可以使用 aGUID作为主键,您将获得更好的可扩展性INSERTS

于 2009-08-25T08:32:56.997 回答
1

老实说,这很棘手。多列分区是一种选择,您可以在多个列上创建基于范围的分区。在 11g 中,您可以将其作为 A 列上的分区和 B 列上的子分区来实现,但在 10g 中,您必须在两列上按范围进行分区。我认为棘手的部分是知道要分区的边界,因为您可能希望两个分区方案“同步”。

于 2009-08-14T15:47:03.793 回答
1

在这种情况下,为了提高“table_id”连接的性能,您还应该将相应的“created_on”存储在您将主要连接的表中。如果你这样做,你总是可以同时加入“table_id”和“created_on”,这样你的“PARTITION RANGE ALL”就会变成“PARTITION RANGE SINGLE”。您可以衡量速度增益并将其与额外的存储成本进行权衡。

编辑:

如何保持两个领域一起增加:

ALTER TABLE my_table MODIFY created_on DEFAULT SYSDATE;

并在所有插入中从序列中填写 ID。

于 2009-08-14T20:38:40.353 回答
0

如何强制两列一起增加?

  1. 假设它是批量加载并且 id 是在批量加载时生成的序列,您可以在加载之间更改序列以更好地控制用于每个分区的序列范围。如果序列和创建时间是在批量加载之前分配的,您可能需要在 ETL 过程中确定每个创建日期的最小/最大 ID 是多少。

  2. created_on 上的范围分区,id 上的范围子分区。每个分区应该只有一个子分区。

  3. 假设,因为这是一个新的数据库,你将有 11g 对虚拟列的检查约束怎么样。虚拟列 date_partition

    CASE WHEN created_on BETWEEN ... AND ... THEN 'PARTITION_1' WHEN created_on BETWEEN ... AND ... THEN 'PARTITION_2' ... END

id_partition 上的类似虚拟列,尽管您必须查询以获得每个分区的最小/最大 PK。应该很快,因为作为主键,上面有一个索引。

然后添加一个约束,使得 id_partition = date_partition

于 2009-08-24T23:00:36.640 回答