Как встроить переменную в PL / SQL?

Ситуация

У меня проблемы с планом выполнения моего запроса для запроса среднего размера по большому объему данных в Oracle 11.2.0.2 .0. Чтобы ускорить процесс, я ввел фильтр диапазона, который делает примерно следующее:

PROCEDURE DO_STUFF(
    org_from VARCHAR2 := NULL,
    org_to   VARCHAR2 := NULL)

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((org_from IS NULL) OR (org_from <= org.no))
   AND ((org_to   IS NULL) OR (org_to   >= org.no)))
  -- [...]

Как видите, я хочу ограничить JOIN из организаций , используя необязательный диапазон номеров организаций. Клиентский код может вызывать DO_STUFF с (предположительно быстрым) или без (очень медленным) ограничением.

Проблема

Проблема в том, что PL / SQL создаст переменные связывания для вышеуказанного org_from и org_to параметры, чего я ожидал в большинстве случаев:

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((:B1 IS NULL) OR (:B1 <= org.no))
   AND ((:B2 IS NULL) OR (:B2 >= org.no)))
  -- [...]

обходной путь

Только в этом случае я измерил, что план выполнения запроса был намного лучше когда я просто вставляю значения, то есть когда запрос, выполняемый Oracle, на самом деле выглядит примерно как

  -- [...]
  JOIN organisations org
    ON (cust.org_id = org.id
   AND ((10 IS NULL) OR (10 <= org.no))
   AND ((20 IS NULL) OR (20 >= org.no)))
  -- [...]

Под "много" я имею в виду в 5-10 раз быстрее. Обратите внимание, что запрос выполняется очень редко, т.е. раз в месяц. Так что мне не нужно кэшировать план выполнения.

Мои вопросы

  • Как я могу встроить значения в PL / SQL? Я знаю о EXECUTE IMMEDIATE , но я бы предпочел, чтобы PL / SQL компилировал мой запрос, и не выполнять конкатенацию строк.

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

  • Я что-то упускаю? Может быть, есть совершенно другой способ улучшить план выполнения запроса, кроме встраивания переменных (обратите внимание, что я тоже пробовал немало подсказок, но я не эксперт в этой области)?

9
задан Lukas Eder 18 March 2011 в 15:33
поделиться