Oracle использует переменную, где, как - PullRequest
2 голосов
/ 16 июля 2010

Я пытаюсь запустить SQL в процедуре PL / SQL. Если бы я сказал:

SELECT * FROM myTable WHERE FNAME like 'Joe%' AND dept = 'xyz';

это выполняется мгновенно.

если я попытаюсь поместить 'Joe' в переменную, это займет вечность, около 3 минут Вот некоторый синтаксис, который я нашел для использования like с переменными.

PROCEDURE myProcedure(firstName IN VARCHAR,
                      cEmployees OUT cursor_type)
IS
BEGIN
     OPEN cEmployees FOR
     SELECT * FROM myTable WHERE FNAME like firstName || '%' AND dept = 'xyz';
END myProcedure;

что я делаю не так? спасибо.

Ответы [ 2 ]

4 голосов
/ 16 июля 2010

Я некоторое время не работал с Oracle.
Тем не менее, вы могли бы избежать этого

SELECT * FROM myTable WHERE FNAME like firstName || '%'

Вместо этого установите переменную firstName перед приведенным выше оператором.
например firstName = firstName || '%' (простите за синтаксис)
а затем SELECT * FROM myTable WHERE FNAME like firstName

0 голосов
/ 16 июля 2010

(извините, комментарий был слишком длинным, поэтому я добавляю его как "ответ")

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

Причина в том, что при повторном анализе запроса (например, когда вы вносите в него небольшое изменение, например, добавление скобок), Oracle генерирует новый план для запроса. Когда он генерирует запрос, он, вероятно, использует просмотр переменной bind, чтобы увидеть, что вы ищете. Когда он анализирует его со значением «Джо», он создает лучший план для этого конкретного значения, и он выполняется быстро. Если, однако, запрос будет повторно проанализирован позже (что, вероятно, будет время от времени по мере старения запроса из общего пула), может быть представлено другое значение (например, «Том») - и Oracle оптимизирует запрос для этого значения, который вполне может быть совсем другой план. Затем, внезапно, запрос на "Джо" выполняется намного медленнее.

Итог: если вы не знаете, почему это стало быстрее, вы не знаете, является ли улучшение постоянным или временным.

Отказ от ответственности: выше приведен только общий совет - если вы укажете версию своей базы данных и предоставите выходные данные плана объяснения для двух запросов, вы можете получить более конкретный совет.

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