我正在设计一个用于按生效日期存储记录的表格,类似于:
CREATE TABLE documents
(
id NUMBER(20,0) NOT NULL,
effective_date_from DATE NOT NULL,
effective_date_to DATE NULL,
documentdata BLOB NOT NULL
)
在此表上执行的主要查询类型是选择对给定生效日期有效的所有记录:
select documentdata from documents where effective_date_from <= '28JUL2015' and (effective_date_to is null or effective_date_to > '28JUL2015')
如您所见,有效列_date_to可以为NULL。首次创建文档时,其effective_date_to未知。只有在稍后,应用程序才会收到文档无效的通知,因此可以更新effective_date_to。
大多数文档在创建后的一到三个月内都会更新有效_date_to,但其中一些文档可能需要数年才能更新。
我估计虽然只有20-30%的文档在某个时间点会有valid_date_to NULL,但它们将受到80%的查询。换句话说,大多数查询使用最近的生效日期。
此表的基数大约为数百万。预计将存储150M至300M之间的物品。
我正在尝试找到这样一个表的最佳分区(和索引)策略,考虑到我的主要目标是提高上述查询的性能。
我的第一个想法是使用基于effective_date_to的RANGE分区,因此不会查找与“旧”记录对应的分区(感谢分区修剪)。
PARTITION BY RANGE (effective_date_to) (
PARTITION t1p1 VALUES LESS THAN (TO_DATE('2015-05-01', 'YYYY-MM-DD')),
PARTITION t1p2 VALUES LESS THAN (TO_DATE('2015-06-01', 'YYYY-MM-DD')),
PARTITION t1p3 VALUES LESS THAN (TO_DATE('2015-07-01', 'YYYY-MM-DD')),
...
PARTITION t1pN VALUES LESS THAN (MAXVALUE)
);
但是,由于effective_date_to在几个月后从NULL更改为其他内容,因此记录可能会从分区移动,从而可能导致碎片。 另一方面,使用其他信息(例如effective_date_from)可能不会带来相同的好处,因为需要查找所有分区。
我想知道我的分区策略是否正确,或者是否应该使用其他策略。
注1:将effective_date_to设置为NULL,可以将其设置为将来很远的日期。事实上,这就是我现在的原型。
注意2:遗憾的是我没有Oracle 12c,因此我无法使用Temporal Validity功能。
谢谢!