Базы данных Oracle - статьи


Том Кайт: о разделении, расщеплении и удалении (On Sharing, Splitting, and Deleting, By Tom Kyte) - часть 2


Давайте сначала рассмотрим, что будет происходить при выполнении одинакового набора запросов с этими тремя значениями параметра. Запросы будут простыми: SELECT * FROM DUAL WHERE DUMMY = <что-то>, где вместо <что-то> будут использоваться литералы 'A' и 'B'. Затем я, используя динамическое представление производительности V$SQL, посмотрю в разделяемом пуле, сколько для каждого запроса было создано курсоров. На листинге 1 показана установка трех значений параметра CURSOR_SHARING, выполнение операторов SELECT и содержимое столбца SQL_TEXT представления V$SQL, показывающее фактические SQL-операторы, которые были использованы в запросах.

SQL> alter session set cursor_sharing=exact; Session altered.

SQL> select * from dual CS_EXACT where dummy = 'A'; no rows selected

SQL> select * from dual CS_EXACT where dummy = 'B'; no rows selected

SQL> alter session set cursor_sharing=force; Session altered.

SQL> select * from dual CS_FORCE where dummy = 'A'; no rows selected

SQL> select * from dual CS_FORCE where dummy = 'B'; no rows selected

SQL> alter session set cursor_sharing=similar; Session altered.

SQL> select * from dual CS_SIMILAR where dummy = 'A'; no rows selected

SQL> select * from dual CS_SIMILAR where dummy = 'B'; no rows selected

SQL> select sql_text 2 from v$sql 3 where sql_text like 'select * from dual CS% where dummy = %' 4 order by sql_text;

SQL_TEXT --------------------------------------------------------- select * from dual CS_EXACT where dummy = 'A' select * from dual CS_EXACT where dummy = 'B' select * from dual CS_FORCE where dummy = :"SYS_B_0" select * from dual CS_SIMILAR where dummy = :"SYS_B_0"

Листинг 1. Значения параметра CURSOR_SHARING: EXACT, FORCE и SIMILAR.

Как видно на листинге 1, с установленным параметром CURSOR_SHARING=EXACT (устанавливается по умолчанию) для каждого уникального SQL-оператора, который я выполняю, в представлении V$SQL создается новая запись – выполняется полный разбор оператора и для него создается новый план выполнения. В разделяемом пуле могут находиться сотни и тысячи очень похожих запросов, которые отличаются только литералами, используемыми в SQL-операторах. Это означает, что в приложении не используются переменные связывания, и это также означает, что сервер базы данных вынужден выполнять полный разбор практически каждого запроса, который, в свою очередь, не только потребляет много процессорного времени, но также приводит и к уменьшению масштабируемости. Сервер не может одновременно выполнять полный разбор сотен и тысяч SQL-операторов, поэтому приложение приостанавливается, ожидая доступа к разделяемому пулу. Один из главных факторов уменьшения масштабируемости в сервере базы данных – не использование переменных связывания. Это было причиной появления а сервере Oracle8i Release 2 (8.1.6) параметра CURSOR_SHARING=FORCE.

С установленным параметром CURSOR_SHARING=FORCE сервер базы данных, как видно на листинге 1, сгенерировал в разделяемом пуле только один разделяемый запрос, заменив 'A' и 'B' на :"SYS_B_0" и сделав курсор совместно используемым многими сеансами, которым он потребовался бы. Вообще говоря, все сеансы многократно использовали бы только один план запроса. Это превратило бы полный разбор в частичный разбор (soft parse), который будет потреблять меньше ресурсов и одновременно увеличивать масштабируемость системы, обеспечивая больший параллелизм, поскольку частичному разбору по сравнению с полным разбором требуется меньше "защелкивать" разделяемый пул (использовать определенный тип блокирования).

Тем не менее, рассматривая пример на листинге 1, вы можете предположить, что установка значений FORCE и SIMILAR приводит к одному и тому же результату, поскольку генерируются одинаковые планы. Итак, какое же различие между этими двумя установками? Для того чтобы показать это различие, мне потребуется другой пример, но сначала я расскажу об этом. Когда в параметре CURSOR_SHARING установлено значение SIMILAR, сервер Oracle Database заменяет все литералы на переменные связывания (так же как и при установке значения FORCE), но в этом случае сервер делает еще одну вещь – он смотрит на каждый заменяемый литерал и задается вопросом: "Могут ли различные значения этой переменной связывания приводить к генерации разных планов?" Например, использование предиката WHERE X=6 подразумевает, что желательно выполнять полный просмотр, а использование предиката WHERE X=5 подразумевает, что желательно выполнять просмотр диапазона по индексу, сервер базы данных распознает такие ситуации и генерирует разные планы. В случае разных планов переменная связывания помечается как ненадежная (unsafe) и ее значение добавляется к сигнатуре этого запроса, так что для повторного использования этого курсора необходимо не только иметь похожие SQL-операторы, но и такое же значение этой конкретной переменной связывания.

Именно поэтому установка значения SIMILAR может, а, с другой стороны, не может уменьшать количество сгенерированных планов, которые можно увидеть в разделяемом пуле. Чтобы показать это, я создам таблицу с некоторыми данными, имеющими очень асимметричное распределение, так что, когда я выполняю запрос с предикатом WHERE ID=1, сервер Oracle Database захочет использовать индекс столбца ID, а когда я выполняю запрос с предикатом WHERE ID=99, сервер Oracle Database не захочет использовать индекс. На листинге 2 показано создание таблицы с данными, имеющими асимметричное распределение, индекса, а также планы выполнения запросов к этим данным.




Начало  Назад  Вперед