Bind переменные oracle что это

Обновлено: 03.07.2024

Oracle имеет два собственных типа переменных. Переменные связи (bind variables) предназначены для хранения отдельных значений присваиваемых при исполнении команды.
Переменные подстановки (Substitution variables) позволяют хранить вводимые вручную перед исполнением команды значения.
Переменные подстановки обозначаются префиксом & . Распознав такую переменную в процессе исполнения Oracle просит ввести ее значение и после ввода продолжает исполнение запроса пользователя. Если символьная переменная в тексте программы записана в одинарных кавычках (например, ‘YEAR_SAL’), при вводе кавычки не ставятся.
Переменная подстановки с двумя амперсендами (например, &&NUM1) запрашивается один раз за сеанс.
Поскольку значения переменных подстановки запрашиваются перед исполнением запроса, то с их помощью может вводиться и часть текста команды.
Например, команда SELECT &STOLBETS . позволяет при каждом исполнении менять имя выводимого столбца.

Команда SQL*Plus DEF[INE] позволяет задать значение переменной на сеанс или до выполнения команды UNDEF[INE] отменяющей определение.
Пример:

DEFINE REM=SAL*12
SELECT ENAME, JOB, REM FROM EMP;

Замечание 1: Команда DEF выдает все определенные переменные, команда DEF <имя> выдает значение указанной переменной, если же она не определена, выдается undefinite.
Команда ACCEPT позволяет определять переменные и присваивать им значения в интерактивном режиме.
Формат команды:

ACC[EPT] имя_переменной [ NUMBER|CHAR ] [ PROMPT|NOPROMPT ‘текст_подсказки’] [ HIDE ]

NUMBER|CHAR -- тип переменной;
PROMPT -- высвечивание подсказки;
HIDE -- скрывает вводимый текст; удобен при вводе паролей.

Для командных файлов, содержащих переменные подстановки используют переменные специального вида. Их девять, имена от 1 до 9. Команда START в этом случае используется в формате:

причем первый фактический параметр заменяет &1, второй &2 и т.д.

Упражнения

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

SELЕСТ ENAME, JOB, MGR, DEPTNO FRОМ EMP WHERE JOB = '&JOB' ;

В появившемся запросе "Enter value for job:" введите MANAGER и в окне SQL*Plus Вы должны получить следующие значения:

2. Определим переменную, представляюшую выражение для вычисления полных годовых начислений сотрудникам. Используем эту переменную в команде, которая находит всех сотрудников, чьи годовые начисления не меньше $30000.

В появившемся запросе "Enter value for job:" введите MANAGER и в окне SQL*Plus Вы должны получить следующие значения:

1. При первом разборе происходит полный разбор запроса (hard parse)
План запроса помещается в глобальный кэш БД с определенным sql_id
2. При повторном выполнении происходит частичный разбор (soft parse)
Происходит только синтаксический разбор, проверки прав доступа и проверки bind переменных. Что для разных вариаций sql_id создает дочерние child_sql_id

Из-за такого механизма работы Oracle вытекает частая проблема oltp систем, где существует огромное число маленьких запросов, отличающихся друг от друга только фильтрами или параметрами. Это приводит к быстрому вытеснению планов из кэша и их последующему повторному hard parse.
В итоге может оказаться, что большую часть времени БД занимается разбором запросов, а не собственно их выполнением.
Отсюда вывод: по возможности используйте bind переменные в вариациях одного запроса, замен константных фильтров, т.к. это даст нам только один план запроса (child_sql_id) при разных значениях переменных на равномерно распределенном столбце.

Я не зря сказал ранее "на равномерно распределенном столбце", т.к. с bind переменными есть проблема: по умолчанию Oracle не знает какие данные будут переданы в запрос и из-за этого может сгенерить неверный план запроса.

Посмотрим на примере по умолчанию. Создадим таблицу с неравномерно распределенным столбцом "n" (9 строк со значением = 1, и 1млн-9 строк со значением 2):
Столбец не имеет гистограмм, но есть статистика по уникальным значениям. Построим план запроса с bind переменной = 1:
Oracle закономерно ожидает в результате половину таблицу и выбирает full scan, хотя мы то знаем, что тут был бы лучше Index scan.

К счастью с 11 версии Oracle может заглядывать в значения bind переменных и подбирать под них нужные планы.
Для этого соберем гистограмму с 2 вершинами и повторим эксперимент:
Oracle сгенерировал новый child_sql_id под новое значение bind переменной и выбрал правильный доступ по индексу.

Данный план был закеширован в глобальную память и если прямо сейчас выполнить заново с параметром 2, то мы получим тотже план (child number 2).

Замечу что на этом этапе уже надо смотреть план уже выполненного запроса, т.к. oracle не умеет показывать план и заглядывать в bind переменные, но при реальном выполнении запроса значения bind переменных смотрятся.

но oracle пометит этот запрос на пересмотр, т.к. план совсем не сошелся с реальными данными и при последующем применении сгенерирует новый child_sql_id (child number 3) под нашу bind переменную:

Из всего этого можно сделать вывод, что вопреки частому заблуждению, Oracle умеет генерировать правильные планы по bind переменным, но делает это не сразу, а при повторном вызове и при наличии гистограммы.
Второе: реальный план запроса с bind переменными можно узнать только во время или после выполнения запроса, т.к. "explain plan" не подсматривает в bind переменные.

Cardinality feedback

Ora Blog
Oracle мониторит и исправляет следующии "estimated rows" оценки на основе реальных "actual rows"
* Single table cardinality (after filter predicates are applied)
* Index cardinality (after index filters are applied)
* Cardinality produced by a group by or distinct operator

Dynamic Sampling

Ora Blog
Применимо для запросов со сложными предикатами фильтрации, которые дают существенную ошибку оптимизатора.
Включение dynamic sampling в зависимости от параметра пробирует от 32 блоков таблицы на предикаты фильтрации и определяем реальный лучший план.

Связываемые переменные, они же prepared statements, они же подготовленные выражения (четко устоявшегося перевода обнаружить не удалось; будем использовать и тот, и тот) — это часть функциональности SQL-баз данных, предназначенная для отделения данных запроса и собственно выполняемого SQL-запроса. Например, у нас есть запрос:
insert into someTable(name) values(‘Вася’);
Что мы можем заметить, просто посмотрев на него? Во-первых, сам запрос insert обычно статичен и не меняется в разных запросах, в 90% случаев просто жестко вбит в коде или генерируется при помощи некоторого ORM; значение данных (в данном случае 'Вася') меняется постоянно и задается извне — из ввода пользователя или из других источников. Связываемые переменные позволяют задать запрос отдельно, а потом передавать данные в него отдельно, приблизительно так (псевдокод):

Так мы отдельно задаем запрос, вместо данных подставляя в него номера связываемых переменных (:1, :2. ) или просто вопросительные знаки. Далее вызываем запрос, указывая, какие именно данные надо подставить вместо указанных переменных.
Результат выполнения этого кода полностью аналогичен результату выполнения запроса insert into someTable(name) values(‘Вася’); , но есть несколько важных отличий, которые будут рассмотрены далее.

Преимущества и особенности связываемых переменных

При использовании связываемых переменных есть несколько преимуществ:
1. Очевидное преимущество — один и тот же подготовленный запрос можно использовать несколько раз для разных данных, тем самым сокращая код.
2. Запросы со связываемыми переменными лучше кэшируются сервером, сокращая время синтаксического разбора.
3. Запросы со связываемыми переменными обладают готовой встроенной защитой от SQL-инъекций.
Рассмотрим каждый пункт подробнее.
Первый пункт очевиден — при наборе данных можно использовать одно и тоже подготовленное выражение несколько раз:

Код генерации SQL-запроса сокращается, а вам любой разработчик скажет, что сокращение объемов кода — это сокращение вероятности ошибки в нем.

Для пояснения второго пункта следует рассказать подробнее, как именно сервер баз данных обрабатывает SQL-запрос. Первейшим этапом выполнения запроса является синтаксический разбор самого запроса, то есть сервер переводит запрос из SQL-языка в какой-то свой внутренний формат, чтобы определить, что именно хочет от сервера клиент. За синтаксическим разбором следует собственно выполнение — составление плана запроса, формирование индексов, сканирование таблиц и множество других неинтересных вещей. Надо отметить, что сам по себе синтаксический разбор — операция довольно «тяжелая» по времени выполнения (хотя бы по сравнению с поиском по индексу, например). Подавляющее большинство современных систем управления базами данных (увы, насколько я знаю, MySQL в данном случае к таковым не относится), «умеют» кэшировать результаты синтаксического разбора и заново использовать их. В этом случае становится очень выгодным, если есть возможность повторять один и тот же SQL-запрос не один раз — будет использоваться синтаксический кэш. Обратимся к примеру в пункте 1 — очевидно, что в данном случае синтаксический разбор выполняется один раз, хотя сам запрос — четыре раза. Если бы мы писали:

то в этом случае каждый раз запрос для сервера был бы новым (потому что анализируется полный текст запроса), и синтаксический разбор пришлось бы выполнить четырежды. Это еще не говоря о том, что такие запросы забивают «мусором» описанный синтаксический кэш.

Перейдем к третьему пункту. Почему же связываемые переменные — это гарантированная защита от SQL-инъекций (по крайней мере, того типа, который рассматривается в упомянутой статье)? Существует заблуждение (у меня оно точно было), что prepared statements – это просто синтаксическая «нашлепка» на команду sql_execute (mysql_real_query, например), которая просто
экранирует все указанные переменные, собирает в одну строку и просто вызывает команду sql_execute, избавляя программиста от некоторого ручного труда. Это не так. На самом деле prepared statement – отдельная возможность в любой вменяемой СУБД. Для этой возможности есть отдельные функции в библиотеке, отдельные места в бинарном протоколе между клиентской и серверной частью СУБД. Более того, собственно подготовленный запрос и данные, которые в нем используются, передаются на сервер отдельно. В клиентских библиотеках есть отдельные команды подготовки выражений (для примера можно посмотреть документацию MySQL C API, PostgreSQL C library).

Примечание: есть исключение — в PHP PDO связываемые переменные по умолчанию эмулируются именно описанным методом, то есть конструированием SQL-команды на клиентской стороне. Это лучше отключать (взято со StackOverflow):

Из этого следует важный вывод — поскольку данные передаются полностью отдельно от запроса, у этих данных нет никаких возможностей модифицировать запрос. Нет возможностей. Вообще никаких. (Экзотические атаки типа переполнения буфера здесь мы не рассматриваем — это совсем другой класс атак).
Данные не нужно экранировать, преобразовывать или как-то менять; они идут в базу данных в точно том виде, в каком нужны нам. Если нам передали строку Robert');drop table students; , не надо заботиться об экранировании, надо просто передать ее как связываемую переменную — ничего она нам не сделает, а так и будет просто лежать в базе данных, как самая обычная строка.

Комментарии к комментариям

В заключение рассмотрим несколько комментариев из уже упомянутой статьи и разберем, что же в них не так:

Rhaps107
а в чем проблема с mysql_real_escape_string? В нём есть какие-то известные уязвимости?

Это мы уже разобрали — проблема с функцией mysql_real_escape_string в том, что ей вообще пользуются. Со связываемыми переменными ей не надо пользоваться. Это экономия на клиентской части (представьте, что функции надо «шерстить» мегабайтную строку, чтобы найти места, где все-таки поставить обратный слэш), а остальные преимущества уже расписаны в статье.

@m_z21
PDO и ORM не панацея. И с использованием pdo можно наделать подобных дыр, если нет понимания как работают sql-инъекции.

Каким боком сюда приплели ORM – непонятно. А вот PDO (и MySQLi) как раз панацея, поскольку SQL injection при их грамотном использовании невозможны, как уже и было описано.

@VolCh21
Выигрыш по потребляемым ресурсам (скорости, памяти), т. к. mysql_* является по сути просто биндингами к libmysql, а mysqli/pdo создают ненужный во многих случаях объектный слой?

И это фактическая ошибка. Команды типа mysqli::prepare — это тоже всего лишь биндинги к соответствующим функциям клиентской библиотеки MySQL. Если желаете убедиться, то можете сами посмотреть на исходные коды PHP. Соответственно, расходы на (якобы ненужный) объектный слой даже если и есть, то они минимальные. Да и экономия на объектном слое уж очень сильно напоминает «экономию на спичках».

Заключение

Надеюсь, мне удалось прояснить для кого-то такую несомненно важную тему, как связываемые переменные (prepared statements). Надеюсь, что многие хотя бы задумаются над тем, чтобы всегда использовать связываемые переменные при работе с БД. Я не претендую на абсолютную полноту и точность изложения, так что буду только рад, если у кого-то найдется что добавить, убавить или откорректировать в написанном.

Переменные связи ( bind-переменные ) служат для передачи значений в СУБД. Эти переменные могут использоваться во фразе WHERE для вычисления условия, в операторах INSERT и DELETE для определения устанавливаемых значений.

Переменные связи , так же как и INTO-переменные, перед применением должны быть предварительно объявлены. Переменные связи при указании их в SQL-операторе предваряются символом "двоеточие".

Курсоры

Под курсором , как правило, понимают получаемый при выполнении запроса результирующий набор и связанный с ним указатель текущей записи. Курсор - это объект, связанный с определенной областью памяти. Существуют явные и неявные курсоры .

Явный курсор имеет имя и перед использованием должен быть объявлен. Неявный курсор создается автоматически и его нельзя повторно открыть без перекомпиляции оператора запроса.

Объявление курсора выполняется оператором DECLARE CURSOR , в котором фраза FOR определяет запрос, ассоциируемый с данным курсором .

создает курсор c1 на базе таблицы tbl1. При объявлении курсора выполнения запроса не происходит. Выполнение запроса и создание курсора инициируется оператором OPEN CURSOR .

создаст курсор , выполнив определенный в нем оператор SELECT .

Приложение получает доступ к данным курсора при последовательном извлечении строк результирующего набора в переменные приложения.

Для извлечения данных из курсора используется оператор FETCH

извлекает значения текущей строки курсора в INTO-переменные .

Для освобождения памяти, выделенной под курсор , его следует закрыть, выполнив оператор CLOSE CURSOR .

Обработка NULL-значений

Для работы с NULL-значениями предусмотрены индикаторные переменные, которые могут использоваться для:

  • определения извлекаемого NULL-значения;
  • внесения NULL-значения в таблицу;
  • фиксирования усекаемых строк.

Если в результате выполнения оператора FETCH или оператора SELECT (возвращающего одну строку) извлекаемые данные принимают значение NULL , то, во-первых, считается, что SQL-оператор выполнен с ошибкой, а во-вторых, в INTO-переменную будет записано значение, отличное от NULL (зависит от типа переменной). Для предотвращения таких ситуаций применяются индикаторные переменные, указываемые после INTO-переменной через символ двоеточия (или INDICATOR :). Если индикаторная переменная принимает отрицательное значение, значит, столбец содержит значение NULL . По умолчанию до выполнения оператора индикаторной переменной присваивается значение 0.

Если в операторе INSERT или UPDATE требуется указать, что используемая переменная связи может содержать значение NULL , то после этой переменной через двоеточие следует записать индикаторную переменную. В этом случае при отрицательном значении индикаторной переменной в базу данных будет занесено значение NULL .

При фиксировании усекаемых строк в индикаторную переменную записывается первоначальная длина строки, а сама строка записывается в переменную основного языка с усечением.

Позиционированные операторы

Для обновления курсора в операторах DELETE и UPDATE может использоваться фраза WHERE CURRENT OF , определяющая, что действие относится к текущей строке курсора . Такой оператор называется позиционированным , и к нему предъявляются следующие требования:

  • и курсор , и оператор должны использовать только одну и ту же таблицу;
  • в запросе, используемом для создания курсора , не должно быть фраз UNION и ORDER BY ;
  • курсор должен удовлетворять критериям обновляемого курсора (например, не применять агрегирующие функции).

Позиционированный оператор DELETE удобно использовать для удаления из таблицы группы строк, предварительно выбранных в курсор .

Обработка ошибок

Стандартом SQL-92 определено две переменных, которые позволяют получать информацию о выполняемом SQL-операторе:

  • переменная SQLSTATE имеет тип char(5) и содержит информацию о классе (два старших символа) и подклассе (3 младших символа), описывающих состояние выполненного SQL-оператора;
  • переменная SQLCODE имеет целочисленный тип и содержит код завершения последнего выполненного SQL-оператора.

Как и другие переменные, используемые во встроенном SQL , переменные SQLSTATE и SQLCODE предварительно должны быть объявлены. Однако переменная SQLCODE может быть создана по умолчанию, если нет объявления другой переменной, получающей информацию о завершении выполнения SQL-оператора.

После выполнения SQL-оператора данные о статусе и коде выполнения автоматически записываются СУБД в эти переменные.

Статус выполнения SQL-оператора может быть определен как:

  • успешное завершение. Соответствует в SQLSTATE коду '00000' (класс '00' ). SQLCODE в этом случае тоже равна 0;
  • успешное завершение с предупреждением. Класс состояния '02' в SQLSTATE определяет предупреждение 'NOT FOUND' ; класс состояния '01' указывает предупреждение, более точно специфицируемое подклассом;
  • завершение с ошибкой. Классы '03' и последующие в SQLSTATE описывают различные ошибочные ситуации (подклассы специфицируют как стандартные ситуации, так и определяемые приложением).

Предупреждение 'NOT FOUND' указывает, что SQL-оператор не содержал ошибки, но не вернул ожидаемого результата. Например, сформированный результирующий набор не содержит ни одной строки, или оператор UPDATE не изменил ни одной строки.

Переменные SQLCODE и SQLSTATE очень часто используются в операторе while для завершения цикла и для выхода из него в случае возникновения ошибки.

Встроенный SQL поддерживает оператор WHENEVER , определяющий действия, которые будут выполнены при возникновении описанной ситуации. Этот оператор следует указывать до выполнения того SQL-оператора, чья обработка ошибок будет "перехватываться".

Оператор WHENEVER влияет на все выполняемые SQL-операторы.

Оператор WHENEVER определяет или метку, на которую будет выполнен переход при возникновении ошибки, или действие типа CONTINUE (продолжение выполнения), или процедуру обработки ошибок.


Переменные связывания - это технический момент, на который стоит обратить внимание в системах OLTP. Хорошая привязка переменных сделает SQL в системной базе данных OLTP очень быстрым, а эффективность использования памяти будет чрезвычайно высокой. Несвязанные переменные могут привести к перегруженности базы данных OLTP, ресурсы потребляются при разборе SQL, и система работает медленно.

Случай этого поста основан на Oracle Database 11g Enterprise Edition Release 11.2.0.4.0


Прежде чем вводить переменные связывания, нам нужно знать, как именно выполняется SQL?

Когда пользователь устанавливает соединение с базой данных, он отправляет в базу данных оператор SQL.После получения этого SQL Oracle сначала выполнит операцию Hash-функции для SQL, чтобы получить значение Hash, а затем перейдет в общий пул, чтобы выяснить, есть ли какие-либо SQL с совпадающим хеш-значением существует.

Если найден, Oracle будет напрямую использовать существующий план выполнения SQL для выполнения текущего SQL, а затем вернет результаты пользователю.

Если не найден, Oracle будет рассматривать это как новый SQL, который будет выполняться в следующем порядке:

1. Грамматический анализ


2. Семантический анализ

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


3. Создайте план выполнения

Этот процесс Oracle составляет окончательный план выполнения SQL после ряда операций, таких как просмотр статистической информации об объекте операции, динамическая выборка и так далее.

Для получения подробной информации о том, как создать план выполнения, вы можете обратиться к событию 10053

4. Выполнить SQL

Oracle выполняет SQL в соответствии с планом выполнения, сгенерированным на предыдущем шаге, и возвращает результат пользователю.

Вышеуказанная работа, которую мы обычно называем сложным анализом, фактически потребляет системные ресурсы. SQL с таким же значением Hash уже существует в общем пуле, называется soft parse.

По сути, связывание переменных означает, что SQL, который изначально требовал от Oracle выполнения жесткого анализа, превращается в мягкий анализ, чтобы сократить время и ресурсы Oracle, затрачиваемые на анализ SQL.

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

Давайте посмотрим на потребление ресурсов связанных и несвязанных переменных для одного и того же SQL, выполненного 10000 раз.

Используйте переменные связывания

Открыть SQL_TRACE

Анализ Tkprof и резюме исходного файла трассировки

После получения файла трассировки на сервере Oracle используйте tkprof для анализа, суммирования и просмотра.

Давайте посмотрим на ключевые части после анализа и обобщения



Весь процесс плюс сгенерированный рекурсивный SQL, мы можем увидеть весь оператор:

ALL NON-RECURSIVE STATEMENTS + ALL RECURSIVE STATEMENTS

  • Время выполнения (истекшее): 0,48 + 0,10 = 0,58 (приблизительно только время выхода)
  • Процессорное время (процессор): 0,48 + 0,09 = 0,57
  • Время анализа (разбор): 8 + 2 = 10
  • Время выполнения (выполнить): 9 + 10017 = 10025

Не используйте переменные связывания

Выполнить сводку анализа tkprof


Просмотр ключевых частей xgj_var_unbind.txt


. Десять миллионов слов опущены в середине


Можно видеть, что каждый из них - это жесткий анализ, который потребляет системные ресурсы и занимает много времени.


Информация о том же исполнении под нашей статистикой:

ALL NON-RECURSIVE STATEMENTS + ALL RECURSIVE STATEMENTS

  • Время выполнения (прошедшее): 1,28 + 15,38 = 16,66
  • Процессорное время (процессор): 1,22 + 15,31
  • Время анализа (разбор): 3 + 20000
  • Время выполнения (выполнить): 4 + 20000

Для сравнения мы можем найти, что В системе OLTP Потребление ресурсов SQL с использованием связанных переменных намного меньше, чем у несвязанных переменных SQL. Чем больше выполнений SQL, тем более очевиден разрыв.

Ресурсы несвязанной переменной SQL в основном используются в сгенерированном рекурсивном SQL, который в основном используется при жестком разборе операторов SQL.

Представьте себе, что когда база данных имеет десятки тысяч и более пользователей, выполняющих такой SQL одновременно, а ORACLE выполняет только жесткий анализ, тот же SQL будет выполнять только операцию выполнения SQL, что неизбежно уменьшит накладные расходы на ресурсы базы данных.

Это происхождение переменной связывания. Она не таинственная, но вместо того, чтобы использовать переменную для замены константы предиката, пусть ORACLE хеширует SQL, отправляемый пользователем каждый раз, чтобы вычислять одно и то же значение хеша, поэтому Oracle будет смотреть на эти SQL Сделайте ту же обработку SQL.

Если для создания базы данных вы используете графический инструмент Oracle DBCA, у вас должно сложиться впечатление: один шаг - попросить вас выбрать тип базы данных OLTP или OLAP. Фактически это показывает, что базы данных OLTP и OLAP сильно различаются: Oracle необходимо знать архитектуру системы, которую вы выбираете, чтобы можно было установить соответствующие значения параметров в соответствии с архитектурой системы, такой как параметры инициализации.

OLTP каштаны

данные:

сводный анализ tkprof




Вы можете просмотреть проверку выполнения плана полного сканирования таблицы SQL блок данных Очевидно, больше, чем план SQL, выполненный с использованием индекса.

Как видно из файла трассировки, на этапе выборки при полном сканировании таблицы было прочитано более 42093 блоков данных, в то время как индексированные на этапе выборки были прочитаны только 308 блоков данных.

OLAP каштаны

Система OLAP намного сложнее в работе с SQL. Большую часть времени в базе данных OLAP выполняет какой-то отчет SQL. Эти SQL часто используют агрегированные запросы (например, group by), и набор результатов также очень велик. В этом случае Далее, индекс не является неизбежным выбором, и даже иногда производительность полного сканирования таблицы будет зависеть от индекса, даже если один и тот же SQL, если условия предиката отличаются, план выполнения может отличаться

данные

Мы используем следующую команду

Примечание: приведенная выше команда выполняется на клиенте plsql и может поддерживаться, но Команда autotrace, plsql, не очень хорошо поддерживается, поэтому я вошел на хост, где расположен сервер, и выполнил ее, конечно, я также могу работать через клиента sqlplus.




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

в заключении

  1. Системе OLAP вообще не нужно устанавливать переменные привязки, это будет иметь только отрицательные последствия, например, заставит SQL выбрать неправильный план выполнения, позволит Oracle выполнять жесткий анализ для каждого SQL и точно знать значение условия предиката. Это влияет на план выполнения. Выбор имеет решающее значение. Это связано с тем, что в системе OLAP затраты на жесткий анализ SQL незначительны. Ресурсы системы в основном используются для более крупных запросов SQL. По сравнению с запросом ресурсы, потребляемые при разборе SQL, явно незначительны, поэтому оптимальный План реализации становится особенно важным
  2. В системе OLAP дайте Oracle точно знать значение условия предиката, которое напрямую определяет выбор плана выполнения SQL. Способ сделать это - не связывать переменные
  3. В системе OLAP анализ индекса таблицы очень важен, потому что он является источником информации и предложением для Oracle составить правильный план выполнения для SQL.

Когда дело доходит до привязки переменных, мы должны упомянуть новую функцию, введенную в Oracle9i, которая называется bind peaking, как следует из названия, когда сложно выполнить синтаксический анализ оператора SQL, Oracle будет смотреть на значение текущего предиката SQL, чтобы сгенерировать наибольшее количество Хороший план исполнения.

Следует подчеркнуть, что пик привязки происходит только при жестком анализе, то есть, когда SQL выполняется в первый раз, последующие переменные не будут просматривать.

Просмотр привязки в конечном итоге не решает проблему разных планов выполнения, вызванных разными предикатами, а может только сделать план выполнения более точным, когда SQL выполняется впервые. OLAP по-прежнему не должен использовать переменные связывания.

Для системы OLTP та же частота повторения SQL очень привлекательна: если оптимизатор Fan Lake анализирует SQL, он неизбежно потребляет ресурсы. Кроме того, результаты пользовательских запросов в системе OLTP, как правило, очень малы, в основном будут учитываться индексы. При проверке привязки был получен правильный план выполнения во время первого жесткого анализа. Последующий SQL выполняется в соответствии с этим планом, что может значительно повысить производительность системы. Это определяется характеристиками системы OLTP.

Читайте также: