Что лучше? Подзапросы или внутреннее объединение десяти таблиц? - PullRequest
13 голосов
/ 07 февраля 2011

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

Пока мы проводили рефакторинг старого кода, мы нашли несколько SQL-запросов со следующим шаблоном (запросы упрощены, например, для целей):

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;

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

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

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;

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

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

Ответы [ 4 ]

15 голосов
/ 07 февраля 2011

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

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

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

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

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

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

8 голосов
/ 07 февраля 2011
Подзапрос

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

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

4 голосов
/ 07 февраля 2011

Объединения обеспечат более высокую производительность, но я рекомендую проверять план выполнения всякий раз, когда «оптимизируем» запросы.

2 голосов
/ 07 февраля 2011

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