Oracle противоречивое поведение производительности запроса

1

Рассмотрим следующий запрос:

SELECT * 
  FROM (
    SELECT ARRM.*, ROWNUM 
    FROM CRS_ARRANGEMENTS ARRM 
    WHERE 
       CONCAT(ARRM.NBR_ARRANGEMENT, ARRM.TYP_PRODUCT_ARRANGEMENT) > 
       CONCAT('0000000000000000', '0000') 
    ORDER BY 
      ARRM.NBR_ARRANGEMENT, 
      ARRM.TYP_PRODUCT_ARRANGEMENT, 
      ARRM.COD_CURRENCY) 
WHERE ROWNUM < 1000;

Этот запрос выполняется в таблице, содержащей 10 000 000 записей. При выполнении запроса от Oracle SQL Developer или моего приложения требуется 4 минуты ! К сожалению, это также поведение внутри приложения, которое я пишу. Изменение значения от 1000 до 10 не оказывает никакого влияния, предполагая, что оно выполняет полное сканирование таблицы.

Однако при запуске из SQuirreL запрос возвращается в течение нескольких миллисекунд. Как это возможно? Объяснение плана, сгенерированного в SQuirreL, дает:

Изображение 174551

Но в Oracle SQL Developer создается другой план объяснений для того же запроса:

Изображение 174551

Любая идея, как это различие в поведении возможно? Я не могу понять это. Я пробовал с JPA и сырой JDBC. В приложении мне нужно проанализировать все 10 000 000 записей, и этот запрос используется для поискового вызова, поэтому ожидание 4 минуты не является вариантом (это займет 27 дней).

Примечание. Я использую тот же драйвер Oracle jdbc в SQuirreL и моем приложении, что не является источником проблемы.

  • 0
    Выполните SELECT COUNT (*) .... и посмотрите, сохраняется ли разрыв в производительности. Я предполагаю, что SQuirrel не получает все данные.
  • 0
    Да, все еще там.
Показать ещё 3 комментария
Теги:
rownum

1 ответ

1

По-видимому, это связано с поддержкой национальных языков или NLS. Разработчик Oracle SQL Developer установил значение "голландский" по умолчанию на основе вашего локали, а SQuirreL - BINARY. Это различие заставило оптимизатор использовать разные пути для решения запроса. Чтобы использовать правильный параметр NLS_SORT в сеансе jdbc, необходимо использовать следующую команду:

ALTER SESSION SET NLS_SORT=BINARY

Затем в запросе будут использоваться правильные индексы.

  • 0
    Эти проблемы легче найти, если использовать текстовые планы объяснения. explain plan for select ... и затем select * from table(dbms_xplan.display); покажет разницу в разделе Notes . По какой-то причине каждая IDE, которую я когда-либо использовал, пыталась сделать планы объяснения «красивыми», но не включала важную информацию.
  • 0
    Я тоже это сделал @JonHeller, но информация о ns_sort также не включена. Провели 12 часов с парнями из форумов сообщества оракулов, чтобы найти проблему, чтобы это не было чем-то простым.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню