【发布时间】:2016-09-16 07:15:52
【问题描述】:
我有一个 20 GB 的表,对于某些要求,必须在 DATE1 字段上进行范围分区,并在 DATE2 字段上列出子分区。 在该表上创建了一个虚拟列 (VC) 以从 DATE2 字段中提取数字月份值并将此 VC 用作子分区键。 根据要求,我们将在 DATE1 上有 30 个分区,每个分区在 VC 上都有 12 个子分区。 任何子分区的最大大小可达 5 GB。
注意我无法实现多列分区,因为我们的内置分区管理器不支持它们。 此外,我无法实现 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 ...
【问题讨论】:
-
虚拟列的确切定义是什么?如果您为表格和问题正文中的视图绘制整个 ddl,那就太好了。
-
@FlorinGhita - 添加了他们
-
嗯...您有两个约束:分区约束和查询约束。我试着看看你如何改变观点。看来你唯一可以在这里改变的...
-
嘿,您的应用程序不应该从视图 v_dtx 中选择?
-
@FlorinGhita - 应用程序对视图 v_dtx 执行聚合。因此它显示 date2-wise Total 金额。此外,它允许用户单击 date2 字段。单击相同时,它会通过在 date2 上传递过滤器来显示 m_dtx 表中的所有列。 date1 = trunc(sysdate) 过滤器是硬编码的,因为它预期只选择基于 date1 的每日记录。它的 date2 过滤器没有命中子分区。
标签: oracle plsql partitioning partition