物化视图:涉及分区运算符的聚合查询
Materialised View : Aggregate query involving partitionn operator
运行 插入墙中,尝试在插入 Tablea
后插入满足特定条件的行 Tableb
drop materialized view mv ;
drop materialized view log on tablea ;
create materialized view log on tablea
with rowid, sequence ( tino, price )
including new values;
create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino;
以上将 return ORA-12054: 无法设置 ON COMMIT 刷新属性。
这是一个限制吗?聚合查询中没有分区运算符?
Table 太大了,我希望我的视图只有特定于某个 period/month 的数据
当我如下所示删除 PARTITION(PART_201609)
和 运行 时,我能够成功创建视图:
create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT tino,sum(price)
FROM tablea
group by tino;
-- 编辑 -- 包括 tablea 的 DDL
-- 创建table
create table TABLEA
(
tino NUMBER not null,
price VARCHAR2(200),
dated DATE
)
partition by range (DATED)
(
partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));
您可以使用 the dbms_mview.explain_mview
procedure 查看为什么您建议的查询不能用于提交时快速刷新 MV:
begin
dbms_mview.explain_mview(q'[SELECT tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino]');
end;
/
select capability_name, possible, msgno, msgtxt from mv_capabilities_table;
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT N
REFRESH_COMPLETE Y
REFRESH_FAST N
REWRITE Y
PCT_TABLE N 2067 no partition key or PMARKER or join dependent expression in select list
REFRESH_FAST_AFTER_INSERT N 2169 the materialized view contains partition extended table name
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT N 2157 PCT is not possible on any of the detail tables in the materialized view
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL N 2169 the materialized view contains partition extended table name
REWRITE_PCT N 2158 general rewrite is not possible or PCT is not possible on any of the detail tables
PCT_TABLE_REWRITE N 2185 no partition key or PMARKER in select list
据我所知,没有任何办法解决 2169 错误:
02169, 00000, "the materialized view contains partition extended table name"
// *Cause: Fast refresh of materialized aggregate views and/or materialized
// join views are not supported if they were defined using partition
// extended table names.
// *Action: Create the fast refreshable materialized view without using
// partition extended table names or create the materialized view as
// a complete refresh materialized view.
无论如何,按名称指定分区有点不寻常;您可以通过指定日期范围来实现相同的目的,Oracle 无论如何都会将查询限制在相关分区。您从以下位置获得相同的执行计划:
explain plan for
select tino, sum(price)
from tablea partition(part_201609)
group by tino;
和
explain plan for
select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino;
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 115 | 15 (7)| 00:00:01 | | |
| 1 | HASH GROUP BY | | 1 | 115 | 15 (7)| 00:00:01 | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 115 | 14 (0)| 00:00:01 | 2 | 2 |
| 3 | TABLE ACCESS FULL | TABLEA | 1 | 115 | 14 (0)| 00:00:01 | 2 | 2 |
--------------------------------------------------------------------------------------------------
您会看到比我从虚拟 table 中获得的行数更多的行数,但请注意 PSTART 和 PSTOP 列。
尽管将其用于您的 MV 仍然不够:
begin
dbms_mview.explain_mview(q'[select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino]');
end;
/
select capability_name, possible, msgno, msgtxt from mv_capabilities_table;
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT N
REFRESH_COMPLETE Y
REFRESH_FAST N
REWRITE Y
PCT_TABLE N 2067 no partition key or PMARKER or join dependent expression in select list
REFRESH_FAST_AFTER_INSERT N 2081 mv log does not have all necessary columns
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ONETAB_DML N 2142 COUNT(*) is not present in the select list
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT N 2157 PCT is not possible on any of the detail tables in the materialized view
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL Y
REWRITE_PCT N 2158 general rewrite is not possible or PCT is not possible on any of the detail tables
PCT_TABLE_REWRITE N 2185 no partition key or PMARKER in select list
您需要解决 2067 错误:
02067, 00000, "no partition key or PMARKER or join dependent expression in select list"
// *Cause: The capability in question is not supported when the materialized
// view unless the select list (and group by list if a GROUP BY
// clause is present) includes the partition key or
// PMARKER function reference to the table in question or an expression
// join dependent on the partitioning column of the table in question.
// *Action: Add the partition key or a PMARKER function reference or a join dependent
// expression to the select list (and the GROUP BY clause, if present).
... 与 partition change tracking. You can add a partition marker 有关 select 列表和分组依据,它再次获得相同的执行计划 (PSTART/PSTOP),但现在允许快速-刷新:
explain plan for
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;
select * from table(dbms_xplan.display);
begin
dbms_mview.explain_mview(q'[select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino]');
end;
/
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT Y
REFRESH_COMPLETE Y
REFRESH_FAST Y
REWRITE Y
PCT_TABLE Y
REFRESH_FAST_AFTER_INSERT N 2081 mv log does not have all necessary columns
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ONETAB_DML N 2142 COUNT(*) is not present in the select list
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT Y
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL Y
REWRITE_PCT Y
PCT_TABLE_REWRITE Y
而且您确实可以使用该查询来创建您的 MV:
create materialized view mv
refresh fast on commit
enable query rewrite
as
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;
Materialized view MV created.
如果您想启用 MV 中的所有功能,您可以将 dated
列添加到您的 MV 日志中:
create materialized view log on tablea
with rowid, sequence ( dated, tino, price )
including new values;
并在您的 MV 查询中包含缺失的聚合:
select dbms_mview.pmarker(rowid), tino, sum(price), count(price), count(*)
from tablea a
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino
不相关,但还要注意,如果有益的话,您也可以对 MV 视图日志进行分区:
create materialized view log on tablea
partition by range (dated)
(
partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
)
with rowid, sequence ( dated, tino, price )
including new values;
运行 插入墙中,尝试在插入 Tablea
后插入满足特定条件的行 Tablebdrop materialized view mv ;
drop materialized view log on tablea ;
create materialized view log on tablea
with rowid, sequence ( tino, price )
including new values;
create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino;
以上将 return ORA-12054: 无法设置 ON COMMIT 刷新属性。
这是一个限制吗?聚合查询中没有分区运算符?
Table 太大了,我希望我的视图只有特定于某个 period/month 的数据
当我如下所示删除 PARTITION(PART_201609)
和 运行 时,我能够成功创建视图:
create materialized view mv
refresh fast on commit
enable query rewrite
as
SELECT tino,sum(price)
FROM tablea
group by tino;
-- 编辑 -- 包括 tablea 的 DDL
-- 创建table
create table TABLEA
(
tino NUMBER not null,
price VARCHAR2(200),
dated DATE
)
partition by range (DATED)
(
partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')));
您可以使用 the dbms_mview.explain_mview
procedure 查看为什么您建议的查询不能用于提交时快速刷新 MV:
begin
dbms_mview.explain_mview(q'[SELECT tino,sum(price)
FROM tablea PARTITION(PART_201609)
group by tino]');
end;
/
select capability_name, possible, msgno, msgtxt from mv_capabilities_table;
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT N
REFRESH_COMPLETE Y
REFRESH_FAST N
REWRITE Y
PCT_TABLE N 2067 no partition key or PMARKER or join dependent expression in select list
REFRESH_FAST_AFTER_INSERT N 2169 the materialized view contains partition extended table name
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT N 2157 PCT is not possible on any of the detail tables in the materialized view
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL N 2169 the materialized view contains partition extended table name
REWRITE_PCT N 2158 general rewrite is not possible or PCT is not possible on any of the detail tables
PCT_TABLE_REWRITE N 2185 no partition key or PMARKER in select list
据我所知,没有任何办法解决 2169 错误:
02169, 00000, "the materialized view contains partition extended table name"
// *Cause: Fast refresh of materialized aggregate views and/or materialized
// join views are not supported if they were defined using partition
// extended table names.
// *Action: Create the fast refreshable materialized view without using
// partition extended table names or create the materialized view as
// a complete refresh materialized view.
无论如何,按名称指定分区有点不寻常;您可以通过指定日期范围来实现相同的目的,Oracle 无论如何都会将查询限制在相关分区。您从以下位置获得相同的执行计划:
explain plan for
select tino, sum(price)
from tablea partition(part_201609)
group by tino;
和
explain plan for
select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino;
--------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
--------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 115 | 15 (7)| 00:00:01 | | |
| 1 | HASH GROUP BY | | 1 | 115 | 15 (7)| 00:00:01 | | |
| 2 | PARTITION RANGE SINGLE| | 1 | 115 | 14 (0)| 00:00:01 | 2 | 2 |
| 3 | TABLE ACCESS FULL | TABLEA | 1 | 115 | 14 (0)| 00:00:01 | 2 | 2 |
--------------------------------------------------------------------------------------------------
您会看到比我从虚拟 table 中获得的行数更多的行数,但请注意 PSTART 和 PSTOP 列。
尽管将其用于您的 MV 仍然不够:
begin
dbms_mview.explain_mview(q'[select tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by tino]');
end;
/
select capability_name, possible, msgno, msgtxt from mv_capabilities_table;
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT N
REFRESH_COMPLETE Y
REFRESH_FAST N
REWRITE Y
PCT_TABLE N 2067 no partition key or PMARKER or join dependent expression in select list
REFRESH_FAST_AFTER_INSERT N 2081 mv log does not have all necessary columns
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ONETAB_DML N 2142 COUNT(*) is not present in the select list
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT N 2157 PCT is not possible on any of the detail tables in the materialized view
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL Y
REWRITE_PCT N 2158 general rewrite is not possible or PCT is not possible on any of the detail tables
PCT_TABLE_REWRITE N 2185 no partition key or PMARKER in select list
您需要解决 2067 错误:
02067, 00000, "no partition key or PMARKER or join dependent expression in select list"
// *Cause: The capability in question is not supported when the materialized
// view unless the select list (and group by list if a GROUP BY
// clause is present) includes the partition key or
// PMARKER function reference to the table in question or an expression
// join dependent on the partitioning column of the table in question.
// *Action: Add the partition key or a PMARKER function reference or a join dependent
// expression to the select list (and the GROUP BY clause, if present).
... 与 partition change tracking. You can add a partition marker 有关 select 列表和分组依据,它再次获得相同的执行计划 (PSTART/PSTOP),但现在允许快速-刷新:
explain plan for
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;
select * from table(dbms_xplan.display);
begin
dbms_mview.explain_mview(q'[select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino]');
end;
/
CAPABILITY_NAME P MSGNO MSGTXT
------------------------------ - ---------- ------------------------------------------------------------------------------------------
PCT Y
REFRESH_COMPLETE Y
REFRESH_FAST Y
REWRITE Y
PCT_TABLE Y
REFRESH_FAST_AFTER_INSERT N 2081 mv log does not have all necessary columns
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ONETAB_DML N 2146 see the reason why REFRESH_FAST_AFTER_INSERT is disabled
REFRESH_FAST_AFTER_ONETAB_DML N 2142 COUNT(*) is not present in the select list
REFRESH_FAST_AFTER_ONETAB_DML N 2143 SUM(expr) without COUNT(expr)
REFRESH_FAST_AFTER_ANY_DML N 2161 see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT Y
REWRITE_FULL_TEXT_MATCH Y
REWRITE_PARTIAL_TEXT_MATCH Y
REWRITE_GENERAL Y
REWRITE_PCT Y
PCT_TABLE_REWRITE Y
而且您确实可以使用该查询来创建您的 MV:
create materialized view mv
refresh fast on commit
enable query rewrite
as
select dbms_mview.pmarker(rowid), tino, sum(price)
from tablea
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino;
Materialized view MV created.
如果您想启用 MV 中的所有功能,您可以将 dated
列添加到您的 MV 日志中:
create materialized view log on tablea
with rowid, sequence ( dated, tino, price )
including new values;
并在您的 MV 查询中包含缺失的聚合:
select dbms_mview.pmarker(rowid), tino, sum(price), count(price), count(*)
from tablea a
where dated >= date '2016-09-01'
and dated < date '2016-10-01'
group by dbms_mview.pmarker(rowid), tino
不相关,但还要注意,如果有益的话,您也可以对 MV 视图日志进行分区:
create materialized view log on tablea
partition by range (dated)
(
partition PART_201608 values less than (TO_DATE(' 2016-09-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201609 values less than (TO_DATE(' 2016-10-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')),
partition PART_201610 values less than (TO_DATE(' 2016-11-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN'))
)
with rowid, sequence ( dated, tino, price )
including new values;