2015-03-06 5 views
1

Рассмотрим следующий запрос:Oracle непоследовательность выполнение запроса

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 запрос возвращает в течение нескольких миллисекунд. Как это возможно? Объяснить план генерируется в беличьих дает:

Explain plan in SQuirreL

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

Explain plan in Oracle SQL Developer

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

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

+0

Сделайте SELECT COUNT (*) .... и посмотрите, все еще есть пробел в производительности. Я предполагаю, что SQuirrel не получает все данные. –

+0

Да, все еще там. – Juru

+0

SQuirreL действительно получает все данные, это не разница. Когда в таблице базы данных загружается только 100 000 записей, такой разницы не было. – Juru

ответ

1

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

ALTER SESSION SET NLS_SORT=BINARY 

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

+0

Эти проблемы легче найти, если используются текстовые планы объяснения. «объяснить план выбора ...», а затем «выбрать» из таблицы (dbms_xplan.display); 'будет показывать разницу в разделе« Примечания ». По какой-то причине каждая среда IDE, которую я когда-либо использовал, попыталась сделать планы объяснений «хорошенькими», но не включила важную информацию. –

+0

Я сделал это также @JonHeller, но информация о ns_sort также не включена. Провел 12 часов с парнями форумов сообщества оракулов, чтобы найти проблему, поэтому это было не просто. – Juru

Смежные вопросы