楼主: newkid

[精华] [翻译]Oracle中的增强子查询优化

[复制链接]
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
61#
 楼主| 发表于 2012-10-15 23:18 | 只看该作者
谢谢指正,确实漏写了两个字,我已经修改过来了。

1、2.3节中, Q5 为什么能展开成Q6,感觉Q6是一个很奇怪的查询。
首先EXISTS可以转换成INNER JOIN:

SELECT * FROM A
WHERE EXISTS (SELECT 1 FROM B WHERE A.KEY = B.KEY)

可以转换成:
SELECT A.*
  FROM A , (SELECT DISTINCT B.KEY FROM B) B2
WHERE A.KEY=B2.KEY;

注意转换后的第二个集合在连接键上必须是唯一的,可以用DISTINCT或GROUP BY来实现,这样连接后才不会导致一行A数据变成多行的情况。

也可以转换成:
SELECT A.*
  FROM A , (SELECT DISTINCT A.ROWID RID FROM A,B WHERE A.KEY = B.KEY) B2
WHERE A.ROWID=B2.RID;


第二种写法把外面的表推入子查询,类似Q6.
Q5原来是针对L1的每一行都执行子查询。Q6把外面的lineitem(L1)推进去后改名LX, 和L2做连接,这样就避开了和外层的相关性,从而避免了逐行操作。
然后它只留下符合要求的那些ROWID, 利用这些ROWID来过滤最外面的lineitem,即外面的那个INNER JOIN。


2、6.2节中,第3点为什么要建立第二个hash 表?

你要理解反连接的工作原理,它先搜索匹配,一旦匹配上,则说明左表的这一行必须丢弃。
如果左表的列都非空,这就很好理解了,比如(1,2,3), 它只要在第二表中搜索(1,2,3),如果搜得到就丢弃,搜不到就返回。
问题出在左表数据行上的空列。例子中的(NULL,2,3),你不能光在第二表中搜索(NULL,2,3)。即使第二表中不存在(NULL,2,3),也不能下结论说左表的这行可以返回。因为如果第二表存在(1,2,3), 那么这也被认为是一种“匹配”:1和NULL的匹配结果是“未知”,所以一旦(1,2,3)存在,则左表的(NULL,2,3)必须被丢弃。但是我们一开始只是建立右表的三个连接列的HASH表,即(C1,C2,C3)的HASH表,这样的结构只能匹配所有列,你不能利用该HASH表来判断(C2,C3)是否存在。C1+C2+C3和C2+C3的HASH结果是完全没有关系的,可能差了十万八千里。
这时候就必须再次引入另一个HASH表,这个HASH表包含了右表所有(C2,C3)的HASH结果。以后一旦碰到(NULL, X, Y)这样的数据,这第二个HASH表都能用上。
有可能这引入的第二个HASH表还不够,因为左表中还可能有(X,NULL,Y)这样的数据,如果碰到了就得在(C1,C3)上再次建立第三个HASH表。

使用道具 举报

回复
论坛徽章:
9
2009日食纪念
日期:2009-07-22 09:30:00ITPUB8周年纪念徽章
日期:2009-09-27 10:21:21祖国60周年纪念徽章
日期:2009-10-09 08:28:002010新春纪念徽章
日期:2010-03-01 11:19:10ITPUB9周年纪念徽章
日期:2010-10-08 09:31:22ITPUB十周年纪念徽章
日期:2011-11-01 16:23:262012新春纪念徽章
日期:2012-01-04 11:53:54ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:152013年新春福章
日期:2013-02-25 14:51:24
62#
发表于 2012-10-16 21:04 | 只看该作者
如果我没理解错的话:
Q6:  SELECT   s_name
  FROM   supplier,   lineitem   L1,
      (SELECT   LX.rowid   xrowid
         FROM   lineitem   L2,   lineitem   LX
        WHERE   L1.l_suppkey <> LX.l_suppkey   AND
                L1.l_orderkey   =   LX.l_orderkey
       GROUP   BY   LX.rowid
       HAVING   SUM(CASE WHEN L2.l_receiptdate > L2.l_commitdate
                         THEN   1   
                         ELSE   0   
                    END)   =   0)   V
WHERE  s_suppkey   =   L1.l_suppkey   AND
        L1.rowid   =   V.xrowid;
这里的L1难道不应该是L2?

另外 Q7里面好像也少了个条件
L1.l_suppkey <> L2.l_suppkey
,group by 里的 S.rowid 貌似也不需要。

2、你的意思是 左表里如果是 (null,2,3) ,那么需要看右表里
存不存在 ( X,2,3)的记录,由于无法穷举右表里的X值 ,所以
索性建一个 (C2,C3)列的hash 表做查找?
重建一个hash 表,再去做hash查找,貌似代价也不小啊。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
63#
 楼主| 发表于 2012-10-16 23:34 | 只看该作者
确实Q6和Q7的原文都有错误!我已经改过来了。我一眼望去没觉得有错,都怪自己的自动纠错能力太强了

关于那个(c2,c3)的HASH表,如果只用一次那当然是没必要,如果左表上类似(NULL,X,Y)的记录有很多行那就合算了。再说为了查找(C2,C3)本来也要将右表走一遍的(可能没走完就找到了),再建一个HASH表其实也是顺便。

使用道具 举报

回复
求职 : 数据库开发
论坛徽章:
2
2013年新春福章
日期:2013-02-25 14:51:24ITPUB社区千里马徽章
日期:2013-08-22 09:58:03
64#
发表于 2012-10-17 15:20 | 只看该作者
mark

使用道具 举报

回复
论坛徽章:
82
2013年新春福章
日期:2013-02-25 14:51:24奥运会纪念徽章:排球
日期:2013-04-11 18:16:37奥运会纪念徽章:曲棍球
日期:2013-04-11 18:16:47奥运会纪念徽章:垒球
日期:2013-04-27 15:03:48奥运会纪念徽章:跳水
日期:2013-04-27 15:04:27奥运会纪念徽章:举重
日期:2013-04-27 15:04:27奥运会纪念徽章:田径
日期:2013-04-27 15:04:27奥运会纪念徽章:赛艇
日期:2013-04-27 15:04:27奥运会纪念徽章:垒球
日期:2013-04-27 15:04:27咸鸭蛋
日期:2013-03-24 21:25:32
65#
发表于 2012-10-17 21:32 | 只看该作者
下了很多功夫啊。

使用道具 举报

回复
论坛徽章:
6
祖国60周年纪念徽章
日期:2009-10-09 08:28:002010年世界杯参赛球队:阿尔及利亚
日期:2010-06-19 23:30:06ITPUB9周年纪念徽章
日期:2010-10-08 09:31:212010广州亚运会纪念徽章:篮球
日期:2011-02-10 14:31:35参与SAP云计算之旅活动纪念
日期:2011-05-17 13:35:452012新春纪念徽章
日期:2012-01-04 11:54:26
66#
发表于 2012-10-22 15:03 | 只看该作者
太赞了,学习

使用道具 举报

回复
论坛徽章:
1
迷宫蛋
日期:2013-03-25 12:00:30
67#
发表于 2013-4-25 20:03 | 只看该作者
MARK

使用道具 举报

回复
论坛徽章:
0
68#
发表于 2013-10-6 15:21 | 只看该作者
好样的,向你致敬。

使用道具 举报

回复
论坛徽章:
0
69#
发表于 2013-10-7 06:28 | 只看该作者
长知识了,谢谢楼主

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表