我正在设计一个新的实验室数据库。
我的主要数据表至少包含id (PK NUMBER)
和created_on (DATE)
。此外,对于任何两个条目,具有较高id
的条目将具有较晚的created_on
日期。
我计划按created_on
进行分区,以提高最近输入数据的效果。由于列一起增加,因此表也将由id
隐式分区。 Oracle不会知道id
隐含的分区,以利用id
上的表连接分区。
两个问题:
如何强制同时增加两个列?
如何利用表连接的隐式分区?
答案 0 :(得分:4)
在我看来,分区的决定应该更多地基于对表维护活动(清除,存档等)的需求而不是性能。在你的情况下,我猜你可能会在样本上对日期范围执行索引范围扫描,因此请确保日期索引也是本地(而不是全局)分区。如果截断分区,这也将消除重建索引的需要。我还猜测PK上的连接将使用rowid的搜索,这样就会在索引范围扫描之后发生,并且分区无法对此产生影响。
[编辑]
关于PK和CREATED_ON列的关联,我使用了几个系统,这些系统从一个前缀为YYYYMMDD的序列构造数字键,并且运行良好。你必须:
自由估计数量 您每天都会有样品
定义一个以此为序列的序列 最大值,然后循环回来 0
有一个返回YYYYMMDD的函数 || {序列值左边填充与 在需要密钥时从触发器或应用程序代码调用的零到适当的固定长度
有些人不同意在密钥中嵌入含义,但在实践中,查看样本ID并了解何时处理它是有用的
答案 1 :(得分:2)
真正重要的问题是:您是否需要按ID范围进行查询?您不太可能需要使用ID BETWEEN :A AND :B
构建查询。因此,Oracle不会从相关分区方案中受益。对于所有重要事项,您可以使用GUID
作为主键,您将获得INSERTS
更好的可伸缩性。
答案 2 :(得分:1)
说实话,这很棘手。多列分区是一种选择,您可以在多个列上创建基于范围的分区。在11g中,您可以将其作为分区A和分区B上的分区,但在10g中,您必须在两列上按范围分区。我认为棘手的部分是知道分区的边界,因为你可能希望两个分区方案“同步”。
答案 3 :(得分: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。
答案 4 :(得分:0)
如何强制执行这两列 一起增加?
假设它是一个批量加载,并且id是在批量加载时生成的序列,您可以在加载之间进行更改,以便更好地控制用于每个分区的序列范围。 如果序列和创建时间是在批量加载之前分配的,那么您可能需要在ETL过程中使用一个阶段来计算每个创建日期的最小/最大ID。
在id上创建了__,Range subpartition的范围分区。每个分区应该只有一个子分区。
假设,由于这是一个新的数据库,你将有11g如何对虚拟列进行检查约束。 虚拟列date_partition
在创建__ BETWEEN ...并且......那么'PARTITION_1'的情况下 当created_on BETWEEN ......和......那么'PARTITION_2' ... END
id_partition上的类似虚拟列,但您必须查询以获取每个分区的最小/最大PK。应该很快,因为作为主键,它上面有一个索引。
然后你添加一个约束 id_partition = date_partition