我可以看到行数存在差异,但我仍然无法理解&解释它。
sel a.15 ,b.16 , c.17, d.18 from
a LOJ b on (a.1=b.1 and a.2=b.2 and a.3=b.3 and a.4=b.4 and a.5=b.5 )
LOJ c on ( a.1=c.1 and a.2=c.2 and a.3=c.3 and a.4=c.4 and a.5=c.5)
LOJ d on ( a.6=d.6 and a.7=d.7 and a.3=d.3 and a.4=d.4)
group by 1,2,3,4
表a
是十亿+行事实表,a
的PI键无法参与联接,但联接中存在b
和c's
个PI键以及d
的一些PI键。
所以我改写为
select < same keys >
from a LOJ ( select <keylist here> from
b JOIN c
on
(b.1=c.1 and b2.=c.2 and b3=c.3 and b4=c.4 and b.5=c.5)
JOIN d
on ( b.3=d.3 and and b.4=d.4)
) e
on
( e.1=a.1 and e.2=a.2 and e.3=a.3 and e.4=a.4
and e.5=a.5 and e.6=a.6 and a.7=e.7 )
group by <col list>
/*DT e created that joins b c and d.Though I joined on 3 and 4 before
with b and d I took them again in the derived table e
and used them again to improve query efficiency */
以上查询运行速度更快 - 1/4 Impact CPU和&gt;线轴50%的折扣但是
我看到小行数差异。所以我的逻辑是a
是LOJ与这些表b,c,d
分开。重写只会给LOJ提供a
一个表格,而b,c,d
是一种融合的表格(如果愿意的话,可以使用融合表格#39;)。 a
如果单独LOJ或连接到单个表,它是如何重要的。但它确实 - 我正在失去行,我想知道如何。我知道IJ可以像这样重写,但LOJ不是一样的。计数(*)有一个小的差异 - 大约15行/百万。好吧,我的问题是我在第二个查询中添加了哪些修改,因此也可以包含15行(delta),并且查询是等效的。
在再次看到这个之后好好思考...我明白他们如何能够给出不同的结果(因为我是LOJ&a
分开三次)但我的问题是我应该添加到第二使它等同于第1。
答案 0 :(得分:1)
你的两个问题不一样。
看看第一个查询。 在其中,最初加入b中的所有记录。由于左连接,这也给出了a中的所有记录,即使它不存在于b中。然后将该结果集与c连接。同样,检索'a'中的所有记录。 d和a之间的连接也是如此。这里,b,c和d彼此独立。
但是,在第二个查询中,您将执行b和c之间的内部联接。这实际上意味着只提取其键位于 b和c中的行。此结果集再次与 INNER 连接,导致丢失少量记录。这是您最后加入的最终产品。记录在子选择中丢失。
您现在正在观察一个小差异,因为大多数记录可能在内部联接期间获得了匹配。但是,您的优化与原始方法不同。