Медленный запрос в Java от JDBC, но не в других системах (TOAD) - PullRequest
5 голосов
/ 27 августа 2009

Здравствуйте, у меня есть запрос к Oracle System, который включает представление, которое объединяет другие таблицы путем применения TO_NUMBER () к первичному ключу таблиц.

Если я выполняю запрос с использованием TOAD, запрос выполняется очень быстро (1 секунда для 800 регистров). Если я выполняю тот же запрос в java-программе от JDBC с литералом String (не параметризованным запросом), время тоже хорошее.

Но если я использую параметризованный запрос PreparedStatement, запрос занимает 1 минуту, чтобы получить те же регистры. Я знаю, что использование константных значений дает отличный план выполнения, чем использование параметров ... но если я удаляю функции TO_NUMBER в соединениях представления, параметризованный запрос также выполняется быстро.

  • Предотвращает ли объединение параметров / TO_NUMBER () использование индекса PK объединяемых таблиц?
  • Есть ли обходной путь для решения этой проблемы (мне нужны параметры запроса, а также функция TO_NUMBER)?

P.D. извините за мой плохой английский

Ответы [ 3 ]

1 голос
/ 27 августа 2009

Убедитесь, что тип данных переменной Java, передаваемой в параметре, совместим с типом данных Oracle. Я видел симптомы, аналогичные вашим, при передаче Java TIMESTAMP через переменную связывания, которая сравнивалась со столбцами Oracle DATE - запрос литеральной строки в порядке, контрольный пример в PL / SQL с привязкой (дата) в порядке, код Java с несоответствием не в порядке.

[Изменить] Я думаю, что вы предоставили некоторую дополнительную информацию с момента первоначальной публикации. Лучший способ понять, что происходит с немного различными формами (связывания и литералы) запроса из разных сред (Java против Toad), - включить трассировку во время выполнения и сравнить пути выполнения из полученных файлов трассировки. Для этого вам потребуется доступ к хосту базы данных для получения файлов.

  • В Toad откройте интерактивный SQL окно (я не использую жабу, но я уверен, ты поймешь о чем я) выполнить команду SQL "изменить сеанс set sql_trace = true "
  • Запустите ваш запрос - это было бы хорошо Идея добавить комментарий к запросу например, "/ * Жаба с литералами * /"
  • Для теста Java создайте контрольный пример который выдает "alter session ..." заявление, а затем запускает запрос. Снова добавьте комментарий к запросу идентифицировать его как пришедший с Java тест.
  • Не беспокойтесь о включении трассировки выключено - это произойдет, когда сеансы отключены, а в некоторых случаи отключения метода остановка трассировки является предпочтительной.
  • Узнайте, где находятся ваши файлы трассировки хост базы данных "выбрать значение из параметра v $, где имя как 'user_dump_dest' "
  • Найдите файлы .trc, выполнив поиск строки комментария к запросу
  • Используйте утилиту TKPROF из ОС командная строка для обработки трассировки файл - "tkprof filename.trc tkprof filename.out "
  • Изучение / публикация путей выполнения и раз, что вы видите.
1 голос
/ 27 августа 2009

без дополнительной информации мы можем только предполагать, что индекс не используется с функцией to_number (), примененной к столбцу. Как показано в этом вопросе SO , преобразование типов может помешать оптимизатору использовать индекс.

В целом:

  • при добавлении функции в столбец (i-e: to_number(id)) оптимизатор не сможет использовать обычные индексы для этого столбца,
  • если это возможно, вы должны использовать столбец raw. Например: вместо WHERE trunc(col) = DATE '2009-08-27' вы должны использовать: WHERE col >= DATE '2009-08-27' AND col < DATE '2009-08-28'
  • если вам действительно нужно применить функцию к столбцу, вы можете использовать индекс на основе функции
0 голосов
/ 18 октября 2013

Убедитесь, что кто-то не установил свойство oracle.jdbc.defaultNChar = true

Иногда это делается для решения проблем с юникодом, но это означает, что все столбцы обрабатываются как nvarchars. Если у вас есть индекс для столбца varchar, он не будет использоваться, потому что oracle должен использовать функцию для преобразования кодировки символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...