Что лучше? Подзапросы или внутреннее соединение десяти таблиц?

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

Во время рефакторинга старого кода мы обнаружили несколько запросов sql с шаблоном follow (запросы, например, упрощены):

SELECT
   (
    SELECT X
    FROM A
    WHERE A.id = TABLE.id
   ) AS COLUMN1,
    (
    SELECT Y
    FROM B
    WHERE B.id = TABLE.id
   ) AS COLUMN1,
   (
    SELECT Z
    FROM C
    WHERE C.id = TABLE.id
   ) AS COLUMN1,
   ...
FROM
    TABLE
WHERE
    TABLE.id = @param;

Эти запросы выполняют несколько внутренних подзапросов из столбца each, которые они возвращают.

Мы планируем переписать эти запросы по следующему шаблону:

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on B.ID = TABLE.ID
    INNER JOIN C on C.ID = TABLE.ID
WHERE
    TABLE.id = @param;

С внутренними объединениями они легче читать и понимать, но действительно ли это происходит быстрее? Это лучший способ написать их? К сожалению, первый, который мы переписали, не улучшил время запроса, он сделал запрос немного медленнее.

Вот мой вопрос: нужно ли переписывать все эти запросы? Являются ли эти подзапросы хорошим способом выполнить эту работу? Являются ли они быстрее способом внутреннего соединения?

Ответ 1

Если я правильно понял ваш вопрос, вы начинаете операцию по перезаписи некоторых ваших операторов SQL, потому что вы ДУМАЕТЕ, что с ними может быть проблема.

Мой совет - остановиться и сначала начать определять, где ваше время в настоящее время расходуется. Только после того, как вы обнаружили, что это в запросах с этими скалярными подзапросами И это из-за этих скалярных подзапросов, вы должны переписать их. До тех пор: начните отслеживать и изучать.

Вот два потока из OTN, которые используются для управления людьми с проблемами производительности:

http://forums.oracle.com/forums/thread.jspa?messageID=1812597 http://forums.oracle.com/forums/thread.jspa?threadID=863295

С уважением,
Роб.

И: из-за скалярного кэширования подзапросов исходный запрос может быть намного быстрее, чем перезаписанный запрос с использованием объединений.

Ответ 2

подзапрос действительно выполняется один раз для каждой строки, тогда как соединение происходит по индексам.

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

Ответ 3

Joins даст вам лучшую производительность, но я рекомендую взглянуть на план выполнения всякий раз, когда "оптимизируют" запросы.

Ответ 4

Как этот ответ утверждает, он не должен влиять на производительность. Тем не менее, некоторые оптимизаторы запросов могут работать лучше на JOIN, поэтому вы должны сделать некоторые эксперименты в своей системе.

И теперь для чего-то совершенно другого: JOIN для каждой таблицы для следующей может быть более эстетичным, чем JOIN все с TABLE и предотвращает ошибки всякий раз, когда идентификатор появляется более одного раза в одной из таблиц

SELECT
    A.X, B.Y, C.Z
FROM
    TABLE
    INNER JOIN A on A.ID = TABLE.ID
    INNER JOIN B on A.ID = B.ID
    INNER JOIN C on B.ID = C.ID
WHERE
    TABLE.id = @param;