给定一个包含数百万条目的地址表,由state_cd分区:
CREATE TABLE ADDRESSES
(
ADDRESS_ID INT NOT NULL PRIMARY KEY,
STATE_CD VARCHAR2(2) NOT NULL,
CITY VARCHAR2(100) NOT NULL
)
PARTITION BY LIST(STATE_CD)
(PARTITION P_AL VALUES ('AL'),...., PARTITION P_WY VALUES ('WY'));
每天有数百万次测量的测量表,按日期划分范围:
CREATE TABLE MEASUREMENTS
(
MEASUREMENT_ID INT NOT NULL PRIMARY KEY,
MEASUREMENT_DT DATE NOT NULL,
ADDRESS_ID INT NOT NULL,
MEASUREMENT NUMBER NOT NULL,
CONSTRAINT MEASUREMENTS_FK1 FOREIGN KEY (ADDRESS_ID)
REFERENCES ADDRESSES (ADDRESS_ID)
)
PARTITION BY RANGE (MEASUREMENT_DT)
(PARTITION P_20150101 VALUES LESS THAN (DATE '2015-01-02'),...);
通过分区连接MEASUREMENTS和ADDRESSES可以大大改善许多查询,例如:
SELECT TRUNC(MEASUREMENT_DT) MNTH,
CITY,
AVG(MEASUREMENT)
FROM MEASUREMENTS
JOIN ADDRESSES USING (ADDRESS_ID)
GROUP BY TRUNC(MEASUREMENT_DT), CITY;
然而,将STATE_CD添加到MEASUREMENTS是违反正常形式的行为(引入全新的性能问题,例如ADDRESSES JOIN MEASUREMENTS USING (ADDRESS_ID, STATE_CD)
真的会对CBO的基数估计感到困惑。)
最佳解决方案是通过引用进行子分区,Oracle不支持:CREATE TABLE MEASUREMENTS ... PARTITION BY RANGE(MEASUREMENT_DT) SUBPARTITION BY REFERENCE (MEASUREMENTS_FK1)
。
这似乎是一个相当简单的引用分区应用程序。但不仅语法不受支持;我无法找到很多论坛活动要求这样的功能。这导致我在这里发布:通常当我正在寻找一个其他人都没有寻找的功能时,这意味着我忽略了一个等效(或可能更好)的替代方案。