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


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


SQL> alter session set cursor_sharing=force; Session altered. SQL> select * from t CS_FORCE where id = 1; 1 row selected. SQL> select * from t CS_FORCE where id = 50; no rows selected SQL> select * from t CS_FORCE where id = 99; 48029 rows selected. SQL> select * from t CS_FORCE where id = 1; 1 row selected. SQL> select * from t CS_FORCE where id = 50; no rows selected SQL> select * from t CS_FORCE where id = 99; 48029 rows selected. SQL> alter session set cursor_sharing=similar; Session altered. SQL> select * from t CS_SIMILAR where id = 1; 1 row selected. SQL> select * from t CS_SIMILAR where id = 50; no rows selected SQL> select * from t CS_SIMILAR where id = 99; 48029 rows selected. SQL> select * from t CS_SIMILAR where id = 1; 1 row selected. SQL> select * from t CS_SIMILAR where id = 50; no rows selected SQL> select * from t CS_SIMILAR where id = 99; 48029 rows selected. SQL> select sql_text 2 from v$sql 3 where sql_text like 'select * from t CS% where id = %' 4 order by sql_text; SQL_TEXT ------------------------------------------------ select * from t CS_FORCE where id = :"SYS_B_0" select * from t CS_SIMILAR where id = :"SYS_B_0" select * from t CS_SIMILAR where id = :"SYS_B_0" select * from t CS_SIMILAR where id = :"SYS_B_0"

Листинг 3: Значения FORCE, SIMILAR и данные с асимметричным распределением.

Как видно на листинге 3, когда установлено CURSOR_SHARING=FORCE, генерируется один и только один план выполнения. Это, фактически, план "на все случаи жизни", и в этом случае в нем используется просмотр диапазона по индексу (поскольку оптимизатор для генерации плана обязательно должен был использовать переменную связывания, а в первом разобранном запросе использовался предикат ID=1).

Однако, как видно на листинге 3, когда установлено CURSOR_SHARING=SIMILAR, генерируются три плана, поскольку оптимизатор обнаружил, что для поиска по значениям столбца ID используются различные значения этого столбца, могущие приводить к генерации различных планов (эту информацию дает ему статистика, сбор которой показан на листинге 2). Следовательно, фактическое значение переменной связывания было добавлено к сигнатуре этого плана запроса, и только запрос с точно такой же сигнатурой мог снова использовать этот план. В этом состояла цель выполнения каждого из запросов два раза – показать, что возможно повторное использование курсора. В представлении V$SQL нет шести запросов, есть только четыре. При установке CURSOR_SHARING=SIMILAR повторное использование курсора не гарантируется намеренно.

Итак, означает ли это, что при установке CURSOR_SHARING=SIMILAR для любого уникального набора литералов будет генерироваться новый план? Нет, я уже показывал на листинге 1 пример с таблицей DUAL, когда использовались предложения WHERE DUMMY='A' и WHERE DUMMY='B'. Новый план генерируется только тогда, когда подстановка переменной связывания считается ненадежной. Используя пример из листинга 2, когда выполнялось только ненадежное связывание по столбцу ID, я выполню запрос по этому столбцу и по некоторому другому столбцу, но не буду изменять в предикате значение столбца ID, то увижу повторное использование курсора, как это показано на листинге 4.




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



Книжный магазин