Какой SQL имеет лучшую производительность?

#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 анализирует запрос, а затем выбирает наилучший план на основе статистики. Ваш вывод был бы верным, если бы автор указал некоторые подсказки о порядке соединения и т.д.