我有两个问题。
第一个是旧的查询非ANSI
SELECT
COUNT(ses)
FROM
(SELECT
sa.ses, sa.att, sa.ser,
ccp.sta, ccp.end,
c.id_, c.per, c.is_,
ccp.clt_
FROM
sa, tn, ccp, cp, c,
(SELECT DISTINCT sa.ses
FROM sa, sapa
WHERE sa.ses = sapa.ses
AND sapa.pro IN (61,62)
AND sa.full >= to_date('1/1/2013','mm/dd/yyyy')) sapa1
WHERE
1=1
AND sa.ses = sapa1.ses (+)
AND sa.ses = tn.ses
AND ccp.cli = c.cli
AND c.cus = sa.pro
AND substr(c.hea,1,1) = 'H'
AND sa.ful >= ccp.sta
AND sa.ful < nvl(ccp.end('9/9/9000','mm/dd/yyyy'))
AND sa.ful >= to_date('1/1/2013','mm/dd/yyyy')
AND sa.ful <= sysdate
AND ccp.cli = cp.cli
AND cp.clie = 1
AND sa.proj <> 'MMA'
AND c.pers IS NOT NULL)
第二次我改写为ANSI
SELECT COUNT(SES) FROM (
SELECT
SA.FUL,
SA.SES,
SA.ATT,
SA.SER,
CCP.STA,
CCP.END,
C.ID_,
C.PER,
C.IS_,
CCP.CLT,
SAPA1.PRO,
SAPA1.SES
FROM SESSION_ALL SA
LEFT JOIN (SELECT
SA.SES,
SA.CLT,
SAPA.SES,
SAPA.PRO
,RANK() OVER (PARTITION BY SA.SES ORDER BY SAPA.SES DESC) RNK
FROM SA
INNER JOIN SAPA ON SA.SES = SAPA.SES
WHERE 1=1
AND SAPA.PRO IN (61,62)
AND SA.FUL >= TO_DATE('1/1/2013','MM/DD/YYYY')
)SAPA1
ON SA.SES = SAPA1.SES AND SAPA1.RNK = 1
INNER JOIN TN ON SA.SES = TN.SES
INNER JOIN CCP ON SA.CLT = CCP.CLT
INNER JOIN C ON CCP.CLI = C.CLI
INNER JOIN CP ON CCP.CLI = CP.CLI
WHERE 1=1
AND C.PER IS NOT NULL
AND SUBSTR(C.HEA,1,1) = 'H'
AND CP.CLI = 1
AND SA.PRO <> 'MMA'
AND SA.FUL >= CCP.STA
AND SA.FUL < NVL(CCP.END('9/9/9000','MM/DD/YYYY'))
AND SA.FUL >= TO_DATE('1/1/2013','MM/DD/YYYY')
AND SA.FUL <= SYSDATE
)
当我从两者中删除计数时,他们都很快回来了。当我添加第二个查询不返回结果的计数时,它就会继续运行。非ANSI(第一个查询)非常快速地返回结果。不知道为什么会这样?我不熟悉执行计划
答案 0 :(得分:0)
我很确定你可以大大简化这些查询。
以下查询应该为您提供与第二个查询完成时相同的计数。我认为您根本不需要SAPA1内联视图,因为您正在计算SA.SES和外部加入SAPA1。您也可以只计算行数(使用count(*)),因为您正在尝试计算的列内部连接(这会自动删除空值)。
尝试一下,看看你得到了什么。除非你使用这些表格向我提供一些虚拟数据,否则我无法自己测试。
select count(*)
FROM SESSION_ALL SA
INNER JOIN TN ON SA.SES = TN.SES
INNER JOIN CCP ON SA.CLT = CCP.CLT
INNER JOIN C ON CCP.CLI = C.CLI
INNER JOIN CP ON CCP.CLI = CP.CLI
WHERE C.PER IS NOT NULL
AND SUBSTR(C.HEA,1,1) = 'H'
AND CP.CLI = 1
AND SA.PRO <> 'MMA'
AND SA.FUL >= CCP.STA
AND SA.FUL < NVL(CCP.END('9/9/9000','MM/DD/YYYY'))
AND SA.FUL >= TO_DATE('1/1/2013','MM/DD/YYYY')
AND SA.FUL <= SYSDATE
以下是第一个查询在相同格式中的外观。虽然我个人更喜欢ANSI连接。
SELECT count(*)
FROM
sa, tn, ccp, cp, c
WHERE
sa.ses = tn.ses
AND ccp.cli = c.cli
AND c.cus = sa.pro
AND substr(c.hea,1,1) = 'H'
AND sa.ful >= ccp.sta
AND sa.ful < nvl(ccp.end('9/9/9000','mm/dd/yyyy'))
AND sa.ful >= to_date('1/1/2013','mm/dd/yyyy')
AND sa.ful <= sysdate
AND ccp.cli = cp.cli
AND cp.clie = 1
AND sa.proj <> 'MMA'
AND c.pers IS NOT NULL