我有一个20 GB的表,对于某些要求,必须在DATE1字段上进行范围分区,并在DATE2字段上进行子分区。 在该表上创建一个虚拟列(VC),从DATE2字段中提取数字月份值,并使用此VC作为子分区键。 根据要求,我们在DATE1上将有30个分区,每个分区在VC上都有12个子分区。 任何子分区的最大大小最多可为5 GB。
N.B。我无法实现多列分区,因为我们的内置分区管理器不支持它们。 此外,我无法实现RANGE-RANGE分区子分区,因为两个日期字段(DATE1和DATE2)在其中的日期中没有同步,导致INSERT操作失败。
接下来,我在这张表的顶部创建了一个简单的视图。此视图中公开了包括VC在内的所有日期字段。查询SELECT * FROM vw时;计划按预期显示PARTITION RANGE SINGLE。
现在,我有一个Web前端,通过它我可以点击DATE2打开更多细节。它基本上将DATE2作为过滤器传递给另一个表上的查询并显示大量记录(大约300万)。
问题是,在单击DATE2字段时,我无法根据MONTH值(VC)而不是日期来命中子分区。
因此,我想要一个PARTITION LIST SINGLE而不是计划中的当前PARTITION LIST ALL。
问题是,如何编写选择查询以选择SUB分区。我知道我必须在过滤器中使用VC来实现它,但具有讽刺意味的是,Web应用程序无法在后端传递VC,尤其是当我们只显示DATE值(而不是VC)时。 此外,如果我们无法访问子分区,有没有什么办法可以通过使用INDEXES或PARALLELISM来提高性能?
请帮忙。
--***********************************************
--TABLE CREATION STATEMENT
--***********************************************
CREATE TABLE M_DTX
(
R_ID NUMBER(3),
R_AMT NUMBER(5),
DATE1 DATE,
DATE2 DATE,
VC NUMBER(2) GENERATE ALWAYS AS (EXTRACT(MONTH FROM DATE2))
)
PARTITION BY RANGE (DATE1)
SUBPARTITION BY LIST (VC)
SUBPARTITION TEMPLATE (
SUBPARTITION M1 VALUES (1),
SUBPARTITION M2 VALUES (2),
SUBPARTITION M3 VALUES (3),
SUBPARTITION M4 VALUES (4),
SUBPARTITION M5 VALUES (5),
SUBPARTITION M6 VALUES (6),
SUBPARTITION M7 VALUES (7),
SUBPARTITION M8 VALUES (8),
SUBPARTITION M9 VALUES (9),
SUBPARTITION M10 VALUES (10),
SUBPARTITION M11 VALUES (11),
SUBPARTITION M12 VALUES (12)
TABLESPACE M_DATA
)
(
PARTITION M_DTX_2015060100
VALUES LESS THAN (
TO_DATE(' 2015-06-01 00:00:01', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
) SEGMENT CREATION DEFERRED
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS NOLOGGING
STORAGE( INITIAL 1048576 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT
) TABLESPACE M_DATA);
--******************************************
--VIEW ON TOP OF M_DTX:
--******************************************
CREATE OR REPLACE VIEW v_dtx AS
SELECT r_id, TRUNC(date2) date2_dd, vc, SUM(r_amt) amt
FROM m_dtx WHERE date1 = TRUNC(sysdate)
GROUP BY r_id, TRUNC(date2), vc;
--******************************************
--QUERY FIRED FROM WEB-APPLICATION (AFTER CLICKING ON date2_DD):
--******************************************
SELECT * FROM m_dtx WHERE date1 = trunc(sysdate) AND date2 = ''date2_dd'';
--this is where its bypassing the sub-partition as I could not substitute month or VC ...
答案 0 :(得分:2)
我发现打击子分区的唯一方法是以这种方式编写查询:
SELECT *
FROM m_dtx
WHERE date1 = trunc(sysdate)
AND date2 = ''date2_dd''
and vc = EXTRACT(MONTH FROM ''date2_dd'');
所以,你不需要从上一个屏幕获取vc,因为你有date2。
我测试过:
SELECT *
FROM m_dtx
WHERE date1 = trunc(sysdate)
AND date2 = to_date('10-dec-2014','dd-mon-yyyy')
and vc = EXTRACT(MONTH FROM to_date('10-dec-2014','dd-mon-yyyy'));