PL/SQL Developer быстрее выполняет запросы, если содержит комментарии

Я пытаюсь повысить производительность SQL-запроса к базе данных Oracle 10g. У меня есть следующие два запроса:

Запрос 1

SELECT DISTINCT 
    WMS_EVENT_LOG.LOG_ID,
    WMS_EVENT_LOG.EVENT_ARG4,
    WMS_EVENT_LOG.EVENT_TYPE,
    WMS_EVENT_LOG.EVENT_ARG1,
    WMS_EVENT_LOG.EVENT_ARG3,
    WMS_EVENT_LOG.PROD_ITEM_ID,
    TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
    WMS_EVENT_LOG.PALLET_ID,
    WMS_EVENT_LOG.LOG_USER,
    WMS_EVENT_LOG.POSTED_TO_KCAT,
    POSTEDWMSTRANS.POSTTRAN,
    DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM 
    VMR_WMSEVENTLOG WMS_EVENT_LOG, 
    VM_ADJUST_REASON ADJUST_REASON,
    ( 
      SELECT 
          INVENTORY.BOM_TYPE AS POSTTRAN,
          INVENTORY.PROD_ITEM_ID,
          INVENTORY.CMNT,
          INVENTORY.WMSLINK
      FROM 
          VR_BOM INVENTORY
      WHERE 
          INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND 
          INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
          INVENTORY.WMSLINK IS NOT NULL AND 
          INVENTORY.BOM_TYPE <> 'HLD' 
    ) POSTEDWMSTRANS
WHERE 
    WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.EVENT_TYPE = 31 AND
    ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
    ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND ( 
        WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND 
        WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST' 
    ) AND 
    WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
    WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)  

Запрос 2

--VARIABLE report_start_date VARCHAR
--VARIABLE report_end_date VARCHAR

SELECT DISTINCT 
    WMS_EVENT_LOG.LOG_ID,
    WMS_EVENT_LOG.EVENT_ARG4,
    WMS_EVENT_LOG.EVENT_TYPE,
    WMS_EVENT_LOG.EVENT_ARG1,
    WMS_EVENT_LOG.EVENT_ARG3,
    WMS_EVENT_LOG.PROD_ITEM_ID,
    TRUNC(WMS_EVENT_LOG.LOG_DATE) AS LOG_DATE,
    WMS_EVENT_LOG.PALLET_ID,
    WMS_EVENT_LOG.LOG_USER,
    WMS_EVENT_LOG.POSTED_TO_KCAT,
    POSTEDWMSTRANS.POSTTRAN,
    DECODE(POSTEDWMSTRANS.POSTTRAN, 'Y', POSTEDWMSTRANS.CMNT, WMS_EVENT_LOG.EVENT_ARG3) AS CMNT --cmnt = comment
FROM 
    VMR_WMSEVENTLOG WMS_EVENT_LOG, 
    VM_ADJUST_REASON ADJUST_REASON,
    ( 
      SELECT 
          INVENTORY.BOM_TYPE AS POSTTRAN,
          INVENTORY.PROD_ITEM_ID,
          INVENTORY.CMNT,
          INVENTORY.WMSLINK
      FROM 
          VR_BOM INVENTORY
      WHERE 
          INVENTORY.BOM_TDATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') - 15 AND 
          INVENTORY.BOM_TDATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') + 15 AND
          INVENTORY.WMSLINK IS NOT NULL AND 
          INVENTORY.BOM_TYPE <> 'HLD' 
    ) POSTEDWMSTRANS
WHERE 
    WMS_EVENT_LOG.LOG_DATE >= TO_DATE(:report_start_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.LOG_DATE < TO_DATE(:report_end_date, 'YYYY/MM/DD') AND 
    WMS_EVENT_LOG.EVENT_TYPE = 31 AND
    ADJUST_REASON.ADJUST_REASON_CODE NOT IN ('SPL') AND
    ADJUST_REASON.ADJUST_REASON_CODE = WMS_EVENT_LOG.EVENT_ARG1 AND ( 
        WMS_EVENT_LOG.EVENT_ARG1 <> 'MOV' AND 
        WMS_EVENT_LOG.EVENT_ARG2 = 'ADJUST' 
    ) AND 
    WMS_EVENT_LOG.PROD_ITEM_ID = POSTEDWMSTRANS.PROD_ITEM_ID(+) AND
    WMS_EVENT_LOG.EVENT_ARG4 = POSTEDWMSTRANS.WMSLINK(+)

Как видите, единственная разница между двумя запросами — это комментарии вверху.

По какой-то причине, когда я запускаю query 2 несколько раз в разработчике PL/SQL, он завершается менее чем за секунду. Когда я запускаю query 1 несколько раз в одной и той же среде, это занимает 15 секунд.

Я проверил возвращенные строки, и обе возвращают одинаковое количество строк с одинаковыми данными.

Почему запрос 2 завершается быстрее?
Я полагаю, что это может быть настройка в PL/SQL Developer, которая дает мне ложную информацию.

Примечание
Все это изначально было написано для 8i, дорабатываю для 10g.


person Dodzi Dzakuma    schedule 23.07.2014    source источник
comment
выключите pl/sql dev, выключите базу данных, запустите ее снова, запустите plsqldev, запустите запрос 2 ОДИН РАЗ и измерьте, сколько времени требуется для выполнения   -  person Sebas    schedule 23.07.2014
comment
@Sebas Это устаревший код, который я пытаюсь ускорить, поэтому ваше предложение очень ценится.   -  person Dodzi Dzakuma    schedule 23.07.2014
comment
проверить, объяснить план... они разные? возможно, запрос 1 находится в общем пуле, а запрос 2 - нет?   -  person Patrick Bacon    schedule 23.07.2014
comment
Да, есть что-то связанное с общим пулом, поэтому я хочу, чтобы он перезапустил экземпляр (это также сбросит другие пулы). Сравнение планов объяснения было бы хорошей идеей, хотя я склонен думать, что они будут похожи.   -  person Sebas    schedule 23.07.2014
comment
@Sebas, поскольку запрос 1 является существующим устаревшим кодом, это подтверждает объяснение общего пула.   -  person Patrick Bacon    schedule 23.07.2014
comment
В настоящее время я получаю разрешение от администратора баз данных на перезапуск базы данных. Это база данных тестовой среды, но она одновременно используется несколькими разработчиками. @Sebas Я выполнил план объяснения для обоих запросов. В первый раз, когда план объяснения прошел, во второй раз он вернулся как Explained. Я также получил сообщение 'PLAN_TABLE' is old version   -  person Dodzi Dzakuma    schedule 23.07.2014
comment
Угадайте, что произойдет после перезапуска базы данных. Если проблема исчезнет, ​​вы никогда не узнаете, как ее решить, пока она не повторится снова, и тогда вам не будет предоставлена ​​такая возможность. За 20 лет существования Oracle мне практически никогда не приходилось перезапускать Oracle на стабильно исправленных системах (обратите внимание, я сказал практически... да, было несколько случаев). Вы должны иметь возможность выполнять все, что вам нужно, с помощью команд администрирования. Итак, что делает перезапуск? Сбрасывает SGA и все кеши и принудительно запускает все в холодном состоянии. Вы теряете реальную среду настройки, пока все не прогреется.   -  person codenheim    schedule 23.07.2014
comment
да, я предположил, что это был dev, и он мог делать с ним все, что хотел. Кажется, теперь проще запускать команды сброса   -  person Sebas    schedule 23.07.2014
comment
Я не согласен с тем, что это может быть связано с SGA, но он еще даже не просматривал план запросов, поэтому я думаю, что перезапускать Oracle преждевременно.   -  person codenheim    schedule 23.07.2014
comment
База данных была перезагружена, и оба запроса выполняются примерно в одно и то же время. Около 12 секунд, что слишком медленно, но не больше фантомной скорости комментариев. @Себас   -  person Dodzi Dzakuma    schedule 23.07.2014
comment
Хорошо, тогда предположим, что более быстрое время связано с кэшированием. Теперь пришло время оптимизировать ваш запрос :)   -  person Sebas    schedule 23.07.2014
comment
Вы можете получить ddl-скрипт plan_table, который подходит для вашей базы данных Oracle, перейдя в каталог $ORACLE_HOME/rdbms/admin, если вы хотите провести оптимизацию.   -  person Patrick Bacon    schedule 23.07.2014
comment
Проверяйте планы выполнения в памяти (или в ASH, если имеется лицензия) во время их выполнения. Моя дикая догадка, что они разные.   -  person William Robertson    schedule 10.12.2015


Ответы (1)


Первый запрос находится в общем пуле (соответствует существующей устаревшей процедуре, которая указана в комментариях). Первый запрос использует скомпилированный план из общего пула, поэтому время обновления у него меньше, хотя оба запроса имеют один и тот же план объяснения (почему у них может быть другой план объяснения).

person Patrick Bacon    schedule 23.07.2014
comment
@Sebas, codenheim Это был очень совместный ответ. - person Patrick Bacon; 23.07.2014
comment
Буферный кеш более вероятен, чем общий пул. Дополнительное время для синтаксического анализа одного запроса редко заметно, если только не происходит что-то странное, например, большая динамическая выборка. Буферный кеш может легко объяснить разницу более чем в несколько секунд. Хотя что-то в этом вопросе все же кажется неправильным. Если оба запроса выполнялись несколько раз, то ни буферный кеш, ни общий пул не имеют значения. - person Jon Heller; 24.07.2014