使用源表中的虚拟列重写 Oracle 查询
我在 Oracle 11g 中有一个表 demo_fact,它有几个定义如下的虚拟列:
ALTER TABLE demo_fact ADD (demo_measure_from_virtual NUMBER GENERATED ALWAYS AS
(CASE WHEN demo_category_column = 20 THEN demo_numericdata_column ELSE 0 END)
VIRTUAL VISIBLE);
然后我有一个物化视图,定义为
CREATE MATERIALIZED VIEW demo_agg_mv
REFRESH FORCE ON DEMAND
ENABLE QUERY REWRITE
AS
SELECT
demo_dim_one,
demo_dim_two,
SUM(demo_measure_from_virtual) demo_measure_from_virtual
FROM demo_fact
GROUP BY demo_dim_one, demo_dim_two
现在我希望查询重写启动以下查询:
SELECT demo_dim_one, SUM(demo_measure_from_virtual)
FROM demo_fact
GROUP BY demo_dim_one
但事实并非如此。我运行了 EXPLAIN_REWRITE,这里是输出:
QSM-01150: query did not rewrite
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table,
DEMO_FACT, on column, DEMO_MEASURE_FROM_VIRTUAL
QSM-01082: Joining materialized view, DEMO_AGG_MV, with table, DEMO_FACT,
not possible
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table,
DEMO_FACT, on column, DEMO_NUMERICDATA_COLUMN
Backstory: I'm do this with 70M rows and 50 virtual columns (它们都有相同的结构,上面的简单 case 语句,但有不同的比较列和不同的结果列)
这个问题似乎只在事实表具有虚拟列时出现,但将它们更改为非虚拟列会消耗太多磁盘空间。 Oracle 为什么不重写查询?我能做什么来修复它?
I have a table, demo_fact in Oracle 11g and it has several virtual columns defined as such:
ALTER TABLE demo_fact ADD (demo_measure_from_virtual NUMBER GENERATED ALWAYS AS
(CASE WHEN demo_category_column = 20 THEN demo_numericdata_column ELSE 0 END)
VIRTUAL VISIBLE);
Then I have a materialized view defined as
CREATE MATERIALIZED VIEW demo_agg_mv
REFRESH FORCE ON DEMAND
ENABLE QUERY REWRITE
AS
SELECT
demo_dim_one,
demo_dim_two,
SUM(demo_measure_from_virtual) demo_measure_from_virtual
FROM demo_fact
GROUP BY demo_dim_one, demo_dim_two
Now I want Query Rewrite to kick in on the following query:
SELECT demo_dim_one, SUM(demo_measure_from_virtual)
FROM demo_fact
GROUP BY demo_dim_one
but it doesn't. I ran EXPLAIN_REWRITE on and here is the output:
QSM-01150: query did not rewrite
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table,
DEMO_FACT, on column, DEMO_MEASURE_FROM_VIRTUAL
QSM-01082: Joining materialized view, DEMO_AGG_MV, with table, DEMO_FACT,
not possible
QSM-01102: materialized view, DEMO_AGG_MV, requires join back to table,
DEMO_FACT, on column, DEMO_NUMERICDATA_COLUMN
Backstory: I'm doing this with 70M rows and 50 virtual columns (all of them have the same structure, the simple case statement above, but with a different comparison column and a different result column)
This problem seems to only manifest when the fact table has virtual columns, but changing them to non-virtual would consume too much diskspace. Why isn't Oracle rewriting the query? What can I do to fix it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不知道这对您有多大帮助,但 Oracle 要求物化视图分组的所有列都包含在要重写的语句中。 (编辑至少与虚拟列结合使用。这可能是“不是设计使然”...)
如果您尝试对其进行
explain_rewrite
,应该会告诉您它已重写查询。
这可以这样演示:
将在其上定义虚拟列的表:
虚拟列的定义:
物化视图。注意:它按列
a
和b
分组:正如您所观察到的,物化视图将不会被使用:
现在,列
a
和b
被选择并分组(使用外部查询来确保相同的结果集):I don't know how helpful this is for you but Oracle requires all columns that the materialzied view grouped on to be included in the statement to be rewritten. (edit at least in conjunction with virtual columns. This is probably "not by design"...)
If you try to
explain_rewrite
onit should tell you that it has rewritten the query.
This can be demonstrated like so:
A table to on which the virtual column will be defined:
The definition of the virtual column:
The materialized view. Note: it groups on columns
a
andb
:The materialized view will not be used, as you have observed:
Now, both columns
a
andb
are selected and grouped on (with an outer query to ensure the same result set):