如何解决联合查询 - 强制每个查询的哈希唯一
我需要表 T1 和 T2 中 group_name
的唯一值列表。两个表都已分区并包含数亿条记录。我感兴趣的列有一个带有最新统计数据的本地位图索引。此列大约有 500 个唯一值。 (见测试用例)。
鉴于此信息,查找唯一值的最有效方法似乎是:从 T1 中查找 500 个左右的唯一值,然后从 T2 中查找 500 个左右的唯一值,然后对列表进行重复数据删除。所以这转化为这个查询:
select distinct group_name from t1 union
select distinct group_name from t2;
然而,Oracle 生成的实际执行是这样的:
SELECT
SORT UNIQUE <-- 500 records
UNION-ALL <-- 1,430,000,000 records
BITMAP INDEX FFS T1 <-- 1,300,000 records
BITMAP INDEX FFS T2 <-- 130,000 records
因此优化器似乎已将查询重新编写为类似于以下查询的内容,从而有效地跳过了中间步骤中的唯一操作:
select distinct group_name
from (select group_name from t1 union all -- No Unique here
select group_name from t2)
这是我的实际问题: 在不重新编写查询的情况下,我可以仅使用提示来强制执行以下执行计划吗?即我的原始查询的实际编写方式?
SELECT
SORT UNIQUE <-- 500
UNION-ALL <-- 1000
HASH UNIQUE <-- 500 <-- Reduce early
BITMAP INDEX FFS T1 <-- 1,000
HASH UNIQUE <-- 500 <-- Reduce early
BITMAP INDEX FFS T2 <-- 130,000
这是一个创建上面两个表的测试用例。
create table t1(id number,group_name number,payload varchar2(100)) nologging partition by hash(id) partitions 4;
create table t2(id number,payload varchar2(100)) nologging partition by hash(id) partitions 4;
insert /*+ append */ all
into t1
into t2
select rownum as id,mod(rownum,500) as group_name,lpad('x',100,'x') as payload
from dual connect by level <= 1e6;
create bitmap index t1_bx on t1(group_name) nologging local;
create bitmap index t2_bx on t2(group_name) nologging local;
我使用的是 Oracle Database 12c 企业版 12.1.0.2.0 版 - 64 位生产
编辑:
顺便说一句,在准备测试用例时,我找到了两种解决问题的方法,但我仍然想知道是否有办法/*+ hint */
解决问题。
select group_name from t1 group by group_name union
select group_name from t2 group by group_name;
with v1 as(select /*+ materialize */distinct group_name from t1),v2 as(select /*+ materialize */distinct group_name from t2)
select group_name from v1 union
select group_name from v2;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。