Выполняет настройку на «Не существует» и «Существует» - PullRequest
0 голосов
/ 21 сентября 2018
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» содержит более 250 миллионов записей, и это повторяется более двух раз в предложении where, что приводит к огромному времени выполнения

1 Ответ

0 голосов
/ 22 сентября 2018

Аналитические функции были введены в значительной степени для этой цели ... избегайте необходимости читать одну и ту же таблицу более одного раза.Вам нужны два условных аналитических числа - когда читается 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 
   .......
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...