微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

联合查询 - 强制每个查询的哈希唯一

如何解决联合查询 - 强制每个查询的哈希唯一

我需要表 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 举报,一经查实,本站将立刻删除。