Оптимизация сложного запроса множественного объединения в Oracle - PullRequest
0 голосов
/ 11 декабря 2018

Я хочу оптимизировать старый запрос, который сам не писал.Моя проблема в том, что я не привык к такого рода объединениям со старой школой (+) и несколькими предложениями между двумя таблицами.На данный момент выполнение запроса занимает около 15 минут, так как в каждой таблице много строк.

SELECT * 
FROM A, B, C, D, E, F, G
WHERE A.id = B.id
  AND C.id = B.id
  AND A.daytime >= C.daytime
  AND (C.end_date IS NULL OR A.daytime < C.end_date)
  AND A.id = D.id(+)
  AND A.daytime = D.daytime(+)
  AND A.id = E.id
  AND A.daytime = E.daytime(+)
  AND A.id = F.id
  AND A.daytime = F.daytime(+)
  AND custom_function(A.id, 'O', A.daytime) = G.id(+)
  AND A.daytime = G.daytime(+)
  AND A.classname IN('X','Y','Z');

Я не ожидаю, что кто-то перезапишет запрос для меня, а просто направит меня:

  • Могу ли я оптимизировать такой запрос?
  • Если да, использовать ли несколько подзапросов?

Я пробовал сложный набор внутреннего и внешнего соединенияно я не могу понять, что я делаю.Любая помощь будет принята с благодарностью.

РЕДАКТИРОВАТЬ

На самом деле проблема возникает из условия SELECT, потому что я не использую SELECT * в реальном запросе, но куча внешних функций применяется к столбцам, и они являются причиной времени, необходимого для выполнения.Спасибо всем, но нет решения моей проблемы.

1 Ответ

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

Единственные параметры для вашего звонка на custom_function поступают из A.

Количество вызовов, вероятно, будет уменьшено, если вы сделаете что-то вроде:

SELECT * 
FROM (
SELECT A.* (SELECT custom_function(id, 'O', daytime) FROM dual) AS cf FROM A WHERE classname IN('X','Y','Z')
) A_Alias
, B, C, D, E, F, G
WHERE A_Alias.id = B.id
  AND C.id = B.id
  AND A_Alias.daytime >= C.daytime
  AND (C.end_date IS NULL OR A_Alias.daytime < C.end_date)
  AND A_Alias.id = D.id(+)
  AND A_Alias.daytime = D.daytime(+)
  AND A_Alias.id = E.id
  AND A_Alias.daytime = E.daytime(+)
  AND A_Alias.id = F.id
  AND A_Alias.daytime = F.daytime(+)
  AND A_Alias.cf = G.id(+)
  AND A_Alias.daytime = G.daytime(+);

Это уменьшитрассчитайте, удалив эффект умножения записи JOIN и убедившись, что от A отфильтровано как можно больше строк (условие на classname).

Примечание :Я также включил оптимизацию от здесь.
Может не иметь никакого эффекта, но стоит протестировать.
Поиск разделов под названием: Кэширование скалярного подзапроса & СкалярКэширование подзапроса (Пересмотрено) (я предлагаю вам прочитать все это).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...