在哈希分区表的情况下如何使用智能分区联接

问题描述

我有两个大表,它们都由散列分区并且在同一分区键列上分区,并且具有相同数量的分区。 但是我这里有一个问题,我在以下两种情况下的计数是不同的(理想情况下两种情况下的计数应该相等)

1)
select count (1) from tab1 t1,tab t2
Where t1.k = t2.k

2)
select count(1) from tab1 partition (t1_p1) t1,tab2 partition(t2_p1) t2 where t1.k=t2.k;
select count(1) from tab1 partition (t1_p2) t1,tab2 partition(t2_p2) t2 where t1.k=t2.k;
select count(1) from tab1 partition (t1_p3) t1,tab2 partition(t2_p3) t2 where t1.k=t2.k;

在第二种情况下,有8个这样的分区。 理想情况下,由于两种情况下的数据均高于第一种情况下的计数,第二种情况下所有计数的总和应相等,但不相等。 我在这里做错了什么?我期望t1表的第一个分区中存在的所有值都应该在表2的第一个分区中存在,并且第一个表的第二个分区的所有值与第二个表中的第二个分区的值匹配吗?

解决方法

明智的分区联接要求在其联接键上对两个表进行等分,或通过联接键引用分区,因此看起来您尚未在联接谓词中指定分区键,即您需要通过分区键或表添加联接谓词必须通过hash(k)进行分区

,

关于差异的最可能解释是表未分区在K列上。

这是一个简单的演示

CREATE TABLE tab
     (id NUMBER,k NUMBER)
PARTITION BY HASH (id)
PARTITIONS 2; 

CREATE TABLE tab1
     (id NUMBER,k NUMBER)
PARTITION BY HASH (id)
PARTITIONS 2; 

insert into tab (id,k) values(1,0);
insert into tab (id,k) values(2,1);

insert into tab1 (id,1);
insert into tab1 (id,0);

两个表的联接返回两行,如下所示

select * 
from tab
join tab1 
on tab.k = tab1.k;

        ID          K         ID          K
---------- ---------- ---------- ----------
         1          0          2          0
         2          1          1          1

但是,如果您逐个分区地加入分区,则会得到没有行,因为相应的K值位于不同的分区中(请参见不同的列ID

如果表K 上进行了分区,则使用partition extended names(而不是分区名)来引用联接中的单个分区更为安全。请参见下面的示例以获取密钥1

select * 
from tab partition for(1)
join tab1 partition for(1)
on tab.k = tab1.k;

当然,棘手的部分是获取for子句的正确值来引用所有分区,这并不是简单的事情,因为它是Oracle内部机制。看到一些提示here