Oracle mutliple оставил внешние соединения только max () строк - PullRequest
0 голосов
/ 29 ноября 2018

У меня есть заявление, которое часто используется тихо, но работает довольно плохо.Поэтому я хочу оптимизировать его как можно лучше.Оператор состоит из различных частей и союзов.

Одна довольно дорогостоящая часть состоит в следующем.

select * 
from rc050 F
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc0531 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr) FROM rc0531 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
      )
    ) SUB_TABLE1
  ON F.fklz   = SUB_TABLE1.fklz
  AND F.fi_nr = SUB_TABLE1.fi_nr
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc0532 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr) FROM rc0532 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz
      )
    ) SUB_TABLE2
  ON F.fklz   = SUB_TABLE2.fklz
  AND F.fi_nr = SUB_TABLE2.fi_nr
LEFT OUTER JOIN
    (SELECT fi_nr,
      fklz,
      rvc_status,
      lfdnr,
      txt
    FROM rc05311 temp
    WHERE lfdnr =
      (SELECT MAX(lfdnr)
      FROM rc05311
      WHERE fi_nr = temp.fi_nr
      AND fklz    = temp.fklz
      )
    ) SUB_TABLE11
  ON F.fklz   = SUB_TABLE11.fklz
  AND F.fi_nr = SUB_TABLE11.fi_nr
where F.fklz != ' '

Это часть, где мне нужно загрузить эти rc0531 ... rc05311таблицы, что там последняя запись.Есть 11 из этих таблиц, так что это разбито.Как вы можете видеть, я в настоящее время присоединяюсь к каждой таблице с помощью подзапроса и мне нужна только последняя запись, поэтому мне нужен дополнительный подзапрос, чтобы получить максимум (lfdnr).

Пока все это работает хорошо, но я хочу знать, еслиесть более эффективный способ сделать это.

В моем главном списке мне нужно иметь возможность адресовать каждый столбец из каждой из этих таблиц.

У вас, ребята, есть какие-либо предложения?

Это в настоящее время выполняется за 1,3 сек.на 13 тысячах строк, чтобы получить приличное ускорение, это должно снизиться до 0,1 секунды или около того.Опять же, это только одна проблема в большом заявлении, полном неэффективных объявлений.

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

замените левые объединения с:

LEFT OUTER JOIN (
    SELECT fi_nr,fklz,rvc_status,lfdnr,txt FROM rc0531 temp
    WHERE lfdnr = (SELECT MAX(lfdnr) FROM rc0531 WHERE fi_nr = temp.fi_nr AND fklz = temp.fklz)
    ) SUB_TABLE1
  ON F.fklz   = SUB_TABLE1.fklz
  AND F.fi_nr = SUB_TABLE1.fi_nr

на это:

LEFT OUTER JOIN (

    SELECT fi_nr,fklz,rvc_status,lfdnr,txt FROM rc0531 inner join 
    (SELECT fi_nr, fklz, MAX(lfdnr) lfdnr FROM rc0531 group by fi_nr, fklz)x on x.fi_nr=rc0531.fi_nr and x.fklz=rc0531.fklz and x.lfdnr=rc0531.lfdnr

    ) SUB_TABLE1
  ON F.fklz   = SUB_TABLE1.fklz
  AND F.fi_nr = SUB_TABLE1.fi_nr

дайте мне знать, если оно дойдет до 0,1 сек, я думаю, что оно пойдет

0 голосов
/ 30 ноября 2018

Невозможно оптимизировать запрос SQL .Oracle примет ваш запрос и определит план выполнения, который он использует для определения запрошенной вами информации.Вы можете полностью переписать запрос и, если он приведет к тому же плану выполнения, вы получите точно такую ​​же производительность.Чтобы настроить запрос, вам нужно определить план выполнения .

. Вы можете воспользоваться индексом для каждой из этих таблиц, для столбцов (fi_nr, fklz) или, возможно, даже для (fi_nr, fklz, lfdnr)в зависимости от того, насколько избирательным это становится.Невозможно заранее узнать эту информацию, вам просто нужно попробовать.

Вы также должны удалить select * и выбрать только те столбцы, которые вам нужны.Если можно получить только необходимую информацию из индекса, Oracle не нужно будет извлекать фактическую строку таблицы.

...