一个query的改写

[复制链接]
查看11 | 回复7 | 2010-3-1 11:04:59 | 显示全部楼层 |阅读模式
本帖最后由 KEN6503 于 2015-6-12 07:38 编辑
下面是改写前后的query。那位帮忙看看改写的对不起对。谢谢
因为红字部分被用来join了两次, 所以想通过改写, 只读一次红字的部分。改写成join后用蓝字部分join condition。
现在的query。
SELECT A.GBAPP,
DEPOSIT.GBACCT
GLB_DETAIL.GDACCT
FROM (SELECT GBACCT,

GBAPP

FROM (SELECT GBACCT,

GBAPP

FROM TRANS_DTL

UNION ALL

SELECT GBACCT,

GBAPP

FROM TIMES_DTL) B
WHERE EXISTS

(SELECT 1

FROM CROSSREF_DTL, CUST_DTL

WHERE CROSSREF_DTL.GBACCT = B.GBACCT

AND CROSSREF_DTL.GBCIF = CUST_DTL.GBNBR)) DEPOSIT,
(SELECT LOAN.GBACCT,

LOAN.GBAPP,

GLB_DETAIL.GDACCT,

LOAN.GLNAFG

FROM (SELECT *

FROM LOAN_DTL

WHERE EXISTS

(SELECT 1

FROM CROSSREF_DTL, CUST_DTL

WHERE CROSSREF_DTL.GBACCT = LOAN_DTL.GBACCT

AND CROSSREF_DTL.GBCIF =CUST_DTL.GBNBR)) LOAN,

GLB_DETAIL
WHERE TO_NUMBER (GLB_DETAIL.GDACCT) = LOAN.GBACCT(+)) A
WHERE TO_NUMBER (A.GDACCT) = DEPOSIT.GBACCT(+);
改写后:
SELECT LOAN_DEPOSIT.GBAPP,
LOAN_DEPOSIT.GBACCT_2,
D.GDACCT
FROM (SELECT A.GBACCT,
A.GBAPP,
C.GBACCT GBACCT_2,
C.GBAPP GBAPP_2
FROM LOAN_DTL A,
(SELECT DISTINCT GBACCT

FROM CROSSREF_DTL, CUST_DTL
WHERE CROSSREF_DTL.GLCCIF = CUST_DTL.GLNBR) B,
(SELECT GBACCT,

GBAPP

FROM TRANS_DTL
UNION ALL
SELECT GBACCT,

GBAPP

FROM TIMES_DTL) C
WHERE (A.GBACCT(+) = B.GBACCT AND B.GBACCT = C.GBACCT (+) AND NOT (A.GBACCT IS NULL AND B.GBACCT IS NULL))) LOAN_DEPOSIT, GLB_DTL D
WHERE D.GDACCT = LOAN_DEPOSIT.GBACCT(+);

回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
你根本连语法都没写对,又没表结构,又没表间关系(主键外键唯一键),没有人能看懂。
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
本帖最后由 KEN6503 于 2015-6-12 08:24 编辑
newkid 发表于 2015-6-12 03:30
你根本连语法都没写对,又没表结构,又没表间关系(主键外键唯一键),没有人能看懂。
谢谢提醒。
表的结构如下:(我只列出在sql中出现的column)。所有表都没有主,外键约束。
LOAN_DTLGBACCTNot Null constraint, Indexed.
LOAN_DTLGBAPP
GLB_DTLGDACCTNot Null constraint, Indexed.
GLB_DTL GDAPP
TRANS_DTLGBACCTNot Null constraint, Indexed.
TRANS_DTLGBAPP
TIMES_DTLGBACCTNot Null constraint, Indexed.
TIMES_DTLGBAPP
CROSSREF_DTLGBCIFIndexed.
CROSSREF_DTLGBACCTNot Null constraint, Indexed.
CUST_DTLGBNBRNot Null constraint, Indexed.

下面这个query是改写的query。 我有把它简化了一下。 query是可以运行的。 但是不知道是否和原来的等价。
SELECT LOAN_DEPOSIT.GBAPP,

LOAN_DEPOSIT.GBACCT
FROM (SELECT A.GBACCT,
A.GBAPP,
C.GBACCT GBACCT_2,
C.GBAPP GBAPP_2
FROM LOAN_DTL A,
(SELECT DISTINCT GBACCT

FROM CROSSREF_DTL, CUST_DTL
WHERE CROSSREF_DTL.GLCCIF = CUST_DTL.GBNBR) B,
(SELECT GBACCT,

GBAPP

FROM TRANS_DTL
UNION ALL
SELECT GBACCT,

GLCAPL

FROM TIMES_DTL) C
WHERE (B.GBACCT = A.GBACCT(+) AND B.GBACCT = C.GBACCT(+) AND NOT (A.GBACCT IS NULL AND C.GBACCT IS NULL))) LOAN_DEPOSIT, GLB_DTL D
WHERE D.GDACCT = LOAN_DEPOSIT.GBACCT(+);
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
不知道是否和原来的等价
就把结果和原来的正反minus结果都是没有就等价。
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
一直对(+)有阅读障碍


回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
你原来那个都有语法错误,看不懂想要干什么。这样让人怎么判断?
没有主键外键,怎么确定关系?唯一约束有吗?

回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
本帖最后由 KEN6503 于 2015-6-13 04:01 编辑
newkid 发表于 2015-6-13 02:52
你原来那个都有语法错误,看不懂想要干什么。这样让人怎么判断?
没有主键外键,怎么确定关系?唯一约束有 ...
这些表是warehouse的Stage 表。没有主键外键和唯一约束。只有not null, 那些indexes是为了performance加的。
original query其实是 GLB_DETAIL left outer join LOAN_DTL and (TIMES_DTL union all TRANS_DTL). 而LOAN_DTL and (TIMES_DTL union all TRANS_DTL)都有 EXISTS (SELECT 1 FROM CROSSREF_DTL, CUST_DTL WHERE CROSSREF_DTL.GBACCT = B.GBACCT AND CROSSREF_DTL.GBCIF = CUST_DTL.GBNBR) 条件。
那个exists条件用了2次, 表CROSSREF_DTL, CUST_DTL被读了2次, join2次。我想改写一下,先把表CROSSREF_DTL, CUST_DTL 和LOAN_DTL and (TIMES_DTL union all TRANS_DTL) join在一起, 然后join的结果再left outer join。 我觉得这样可以减少table scan 和join。performance会好一些。

EXISTS
(SELECT 1
FROM CROSSREF_DTL, CUST_DTL
WHERE CROSSREF_DTL.GBACCT = B.GBACCT
AND CROSSREF_DTL.GBCIF = CUST_DTL.GBNBR)
回复

使用道具 举报

千问 | 2010-3-1 11:04:59 | 显示全部楼层
抛开语法错误不谈(贴个没错误的SQL那么难吗?)
你的新写法中B做驱动表,外连接A和C, 而旧写法中是用那个相当于C的集合做驱动表的。
回复

使用道具 举报

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

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行