Comments 7
CURSOR_SHARING выставлен в FORCEЧтобы потом героически преодолевать трудности?
Есть вещи, над которыми разработчик не властен. Как автор перевода я не знаю иных подробностей подопытной системы, могу только заметить, что если бы разработчики и администраторы БД всегда находили общий язык, то мир лишился бы очень многих технологий.
Менять параметры БД в угоду тривиального решения одной из задач системы — верный способ нарваться на неприятности в других бизнес-модулях. И хорошо, если все скелеты сразу выпадут из шкафов, а могут и спустя годы…
Менять параметры БД в угоду тривиального решения одной из задач системы — верный способ нарваться на неприятности в других бизнес-модулях. И хорошо, если все скелеты сразу выпадут из шкафов, а могут и спустя годы…
CURSOR_SHARING = force, да еще и установленный на уровне системы, а не сессии, уже давно вызывает больше боли, чем дает пользы. Его по-моему давно убрали из основных тестов и поэтому кол-во багов с ним очень высоко. Есть у меня один клиент, который до сих пор продолжает упорно жрать кактус, постоянно ловя всякие неожиданные баги из версии в версию…
Виктор добрый день! На какой версии выполнялись эти упражнения?
Виктор сейчас в Польше, там праздничные дни, и он мне пока не ответил. Вроде даже у него нет профиля на Хабре, поэтому будем благодарны за инвайт.
Насчет версии у меня есть предположение, что это Oracle 12, впрочем, в 11 тоже скорее всего сработает, насчет 10 и ниже есть сомнения (хотя VPD еще в Oracle 8.1 появился). Программный код выше я не воспроизводил. А какая версия у Вас?
Насчет версии у меня есть предположение, что это Oracle 12, впрочем, в 11 тоже скорее всего сработает, насчет 10 и ниже есть сомнения (хотя VPD еще в Oracle 8.1 появился). Программный код выше я не воспроизводил. А какая версия у Вас?
У меня пара замечаний по сабжу:
1. Для решения этой проблемы есть Adaptive cursor sharing, и он делает именно то, что нужно: на основе гистограмм создает подходящие дочерние курсоры. Если у них это не работало, значит надо было разбираться с причиной почему ACS не работал. Игорь Усольцев делал отличную подробную презентацию в российской юзергруппе оракл (RuOUG). Вообще, советую посещать наши мероприятия.
2. Раз на базе стоит cursor_sharing=force, то можно было просто создать профиль с одним единственным хинтом BIND_AWARE на любом из этих запросов, с указанием параметра force_match=>true.
3. Насчет динамики:
Я еще на 10-ке использовал несколько разных вариантов в зависимости от условий:
3.1 Если был возможен PL/SQL то просто разбивал через IF на пару разных вариантов, грубо говоря: IF cardinality>N then query1 else query2
A cardinality получал одним из быстрых способов.
3.2. Разбиение на union all с доп.подзапросом, например:
И если данные уже промаркированы как в статье(отдельная таблица где помечены «большие/средние/маленькие»), то этот вариант был бы намного проще
4. Здесь неверно:
Это решение абсолютно для противоположной цели: отключение _OPTIM_PEEK_USER_BINDS и удаление гистограм делают в случае, если оракл плодит разные планы, а хочется строго одного и того же для любых биндов.
5. Существует и еще один подход: секционирование с учетом data skew. Тут вариантов много, одним из простейших является интервальное секционирование по «перекошенному» столбцу основного ACCESS предиката. А для статьи из примера удобно было бы секционировать как раз по SMALL/MIDDLE/LARGE, то есть три разные секции, каждая со своей статистикой(причем заработает даже без гистограмм, т.к. достаточно (num_rows-num_nulls)/num_distinct статистик по секции), что дает оптимизатору легко понять селективность столбца в данной секции.
ЗЫ. Надо было Виктору ко мне обратиться, вместе бы посмотрели почему ACS у них не работал.
1. Для решения этой проблемы есть Adaptive cursor sharing, и он делает именно то, что нужно: на основе гистограмм создает подходящие дочерние курсоры. Если у них это не работало, значит надо было разбираться с причиной почему ACS не работал. Игорь Усольцев делал отличную подробную презентацию в российской юзергруппе оракл (RuOUG). Вообще, советую посещать наши мероприятия.
2. Раз на базе стоит cursor_sharing=force, то можно было просто создать профиль с одним единственным хинтом BIND_AWARE на любом из этих запросов, с указанием параметра force_match=>true.
3. Насчет динамики:
Понятно, что исправление приложения и использование параметров как литералов в запросе – это самый подходящий способ решения проблемы, но он ведет к динамическому SQL с его известными недостатками.
Я еще на 10-ке использовал несколько разных вариантов в зависимости от условий:
3.1 Если был возможен PL/SQL то просто разбивал через IF на пару разных вариантов, грубо говоря: IF cardinality>N then query1 else query2
A cardinality получал одним из быстрых способов.
3.2. Разбиение на union all с доп.подзапросом, например:
select/*+ index(t1 (a,b)) */ *
from t1
where ...
and (select count(*) from t1 where ... and rownum<=X)<X
union all
select/*+ full(t1) или index_ffs(t1) */ *
from t1
where ...
and (select count(*) from t1 where ... and rownum<=X)=X
И если данные уже промаркированы как в статье(отдельная таблица где помечены «большие/средние/маленькие»), то этот вариант был бы намного проще
4. Здесь неверно:
Другой путь – отключение запроса связанных переменных (ALTER SESSION SET "_OPTIM_PEEK_USER_BINDS" = FALSE) или удаление гистограмм (ссылка).
Это решение абсолютно для противоположной цели: отключение _OPTIM_PEEK_USER_BINDS и удаление гистограм делают в случае, если оракл плодит разные планы, а хочется строго одного и того же для любых биндов.
5. Существует и еще один подход: секционирование с учетом data skew. Тут вариантов много, одним из простейших является интервальное секционирование по «перекошенному» столбцу основного ACCESS предиката. А для статьи из примера удобно было бы секционировать как раз по SMALL/MIDDLE/LARGE, то есть три разные секции, каждая со своей статистикой(причем заработает даже без гистограмм, т.к. достаточно (num_rows-num_nulls)/num_distinct статистик по секции), что дает оптимизатору легко понять селективность столбца в данной секции.
ЗЫ. Надо было Виктору ко мне обратиться, вместе бы посмотрели почему ACS у них не работал.
Версия Oracle у Виктора 11.2.0.4
Sign up to leave a comment.
Проблема со связанными переменными: как превратить оптимизатор из врага в друга