SELECT *
FROM tableA RS1
INNER JOIN TableB TB
on TB.headkey =Rs1.headerkey
INNER JOIN TableC TC
on TC.headkey =Rs1.headerkey
.....
..... {Several Inner joins on different tables}
.....
WHERE
"RS1"."SQTY" > 0 AND
"RS1"."PP_KEY" = '123' AND
TRIM(BOTH FROM "RS1"."CTOLK") IS NULL AND
NOT ( EXISTS (
SELECT
1
FROM
"tableaA" "RS2"
WHERE
"RS2"."SQTY" > 0 AND
"RS2"."STAT" < '33800' AND
"RS2"."headerkey" = "RS1"."headerkey"
) ) AND
EXISTS (
SELECT
1
FROM
"tableaA" "RS2"
WHERE
"RS2"."SQTY" > 0 AND
"RS2"."STaT" = '33800.100' AND
"RS2"."SDATE" BETWEEN TRUNC(TRUNC(CURRENT_DATE)) - 7 AND TRUNC(TRUNC(CURRENT_DATE)) AND
"RS2"."headerkey" = "RS1"."headerkey"
)
是否有任何有效的方式编写“ WHERE子句”,因为“ tableA”具有超过2.5亿条记录,并且在where子句中重复了两次以上,从而导致执行时间很长
答案 0 :(得分:0)
为此目的引入了很多分析函数……避免必须多次读取同一张表。您需要两个条件分析计数-读取tableA
时(不是全部,只有"SQTY" > 0
的行,如果有区别的话),这些行按headerkey
进行分区,并且计算两个所需的条件计数。然后,您可以过滤读取行(并添加分析函数),替换WHERE
子句的结果。
类似这样的事情:(使用WITH
子句,使代码更具可读性)
WITH
PREP as (
SELECT *,
count(case when "STAT" < '33800' then 1 end)
over (partition by headerkey) as ct1,
count(case when "STAT" = '33800.100'
and "SDATE" between trunc(sysdate) - 7 and trunc(sysdate)
then 1 end) over (partition by headerkey) as ct2
FROM tableA
where "SQTY" > 0
),
RS2 as (
SELECT * -- or just the columns you need
FROM PREP
WHERE "PP_KEY" = '123'
AND TRIM(BOTH FROM "CTOLK") IS NULL
AND ct1 = 0
and ct2 > 0
)
SELECT *
FROM RS1
INNER JOIN TableB TB
on TB.headkey =Rs1.headerkey
INNER JOIN TableC TC
on TC.headkey =Rs1.headerkey
.....
..... {Several Inner joins on different tables}
.....
WHERE
.......