Что лучше? Подзапросы или внутреннее соединение десяти таблиц?
В нашу офис прибыла старая система для некоторых изменений и исправлений, но она также страдает от проблем с производительностью. Мы точно не знаем, что является источником этой медлительности.
Во время рефакторинга старого кода мы обнаружили несколько запросов 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;