#sql #oracle
#sql #Oracle
Вопрос:
У меня есть 2 инструкции sql, как показано ниже. Они могут извлекать один и тот же набор данных. Как я тестировал, кажется, что SQL2 всегда имеет лучшую производительность. И я объяснил оба утверждения. У них одинаковый план выполнения.
Кто-нибудь может помочь объяснить, влияет ли это на производительность при использовании подзапроса здесь? И как мы можем использовать подзапрос для настройки sql?
Большое спасибо!
--SQL 1
SELECT ADDRRF.ENTITYKEYID,
ADDRESS1,
ADDRESS2
FROM WODS_STG.BLIS_ADDRESSREFERENCE ADDRRF
LEFT JOIN WODS_STG.BLIS_ADDRESS ADDR
ON ADDRRF.ADDRESSID = ADDR.ADDRESSID
WHERE ADDRRF.ADDRESSTYPEID = 10
AND ADDRRF.ENTITYID = 3;
--SQL 2
SELECT ADDRRF.ENTITYKEYID,
ADDRESS1,
ADDRESS2
FROM (
SELECT *
FROM WODS_STG.BLIS_ADDRESSREFERENCE
WHERE ADDRESSTYPEID = 10
AND ENTITYID = 3
) ADDRRF
LEFT JOIN WODS_STG.BLIS_ADDRESS ADDR
ON ADDRRF.ADDRESSID = ADDR.ADDRESSID;
Комментарии:
1. Пожалуйста, покажите нам план выполнения. Вы также можете использовать
set autotrace traceonly
в SQL * Plus, чтобы увидеть более подробную информацию о выполнении инструкций (подробности см. в руководстве)2. Я предполагаю, что второй запрос имеет лучшую производительность, поскольку сначала вы фильтруете результат, а затем оставляете их присоединиться.
3. @CiucaS: Это не должно повлиять. Oracle выполняет множество внутренних преобразований при построении планов выполнения. Два запроса, насколько я могу видеть, функционально идентичны. Сасфан, размести оба плана выполнения в своем вопросе и не удаляй раздел «предикаты» из планов. Спасибо.
4. вы собирались ввести слово
FROM
вместо слова «frin», не так ли? Я согласен с @a_horse_with_no_name, нам нужно увидеть планы объяснения этих запросов, но перед этим не забудьте собрать статистикуDBMS_STATS.gather_schema_stats(...
Ответ №1:
Второй запрос может быть быстрее, потому что он считывает данные из области SGA, которая была кэширована первым запросом. Другими словами, первый запрос использует жесткий синтаксический анализ, а второй использует программный синтаксический анализ, потому что у них одинаковый план выполнения. Попробуйте запустить несколько раз оба из них, чтобы выяснить, выполняется ли второй запрос по-прежнему быстрее.
Комментарии:
1. Кэширование определенно может быть причиной воспринимаемой разницы. Но я сомневаюсь, что мягкий и жесткий синтаксический анализ уместны; жесткий синтаксический анализ выполняется даже для немного другого текста, не имеет значения, совпадает ли план выполнения.
2. Вы совершенно правы, но это единственная идея, которая у меня есть, без планов объяснения запросов.
Ответ №2:
SQL 1 :
Здесь sql engine сначала объединяет таблицы BLIS_ADDRESSREFERENCE и BLIS_ADDRESS, а затем применяет предикаты WHERE для фильтрации записей.
SQL 2 :
Здесь sql engine сначала фильтрует записи из таблицы BLIS_ADDRESSREFERENCE, а затем соединяется с таблицей BLIS_ADDRESS. Я думаю, SQL 2 быстрее, поскольку записи фильтра из BLIS_ADDRESSREFERENCE меньше, чем BLIS_ADDRESS.
Комментарии:
1. Маловероятно, что инструкция Oracle SQL выполняется в том же порядке, в котором она написана. В этом случае простое объединение представлений почти наверняка заставит эти два запроса выполняться одинаково.
2. Верно, я написал то, что догадался. План запроса определяется многими факторами. Чтобы понять, что на самом деле происходит за выполнением запроса, я должен использовать dbms_xplan.display_cursor(), чтобы выяснить. https://hourim.wordpress.com/2011/12/29/getting-explain-plan /
3. Oracle анализирует запрос, а затем выбирает наилучший план на основе статистики. Ваш вывод был бы верным, если бы автор указал некоторые подсказки о порядке соединения и т.д.