powered by simpleCommunicator - 2.0.29     © 2024 Programmizd 02
Map
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как работает result cache
50 сообщений из 50, показаны все 2 страниц
Как работает result cache
    #40134060
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня есть некоторые пробелы в понимании работы result cache. В доке и гугле этого не нашел. Да и непонятно, что именно нужно искать.

В общем, если кратко. Есть Oracle 12.1, и древнющая легаси БД, к которой подключается 100500 разных приложений. Все это работает 24 х 7. Есть таблица параметров. В ней примерно 400 строк. Меняются они довольно редко, большая часть не менялась ни разу за последние 15 лет. В AWR отчете я вижу, что какое-то приложение делает примерно миллион запросов к этой таблице в сутки. Конкретно этот запрос создает примерно 3% всей нагрузки на процессор.

У меня была идея обойтись малой кровью и сделать

Код: plsql
1.
alter table parameter_table result_cache (mode force);


Ожидаемый результат: запрос должен пропасть из SQL ordered by CPU Time, и, по идее, в V$RESULT_CACHE_OBJECTS должна появиться строка для каждого закэшированного значения.
Фактический результат: кэш заработал, но не сразу (а почему-то несколько дней спустя). После каждого обновления таблицы result cache инвалидируется (что ожидаемо), но начинает работать снова через несколько часов.

дополнительные подробности как проверялСначала я потренировался на DEV бд, как это работает. Сделал скрипт вроде такого:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare
  param varchar2(100);
  val varchar2(100);
begin
  for i in 1..100000 loop
    select parameter_value
      into val
      from parameter_table
     where parameter_name = param;
  end loop;
end;


В таком виде - работает хорошо, все ок. После выполнения alter table parameter_table result_cache (mode force) этот кусок кода работает в десятки раз быстрее, проц грузит меньше. Проверял V$RESULT_CACHE_OBJECTS - там отображается мой запрос.

Но на самом деле, приложение обращается к таблице не напрямую, а через функцию. То есть там что-то вроде

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
create or replace function get_parameter(p_param_name varchar2) return varchar2 is
  val varchar2(100);
begin
  select parameter_value
    into val
    from parameter_table
   where parameter_name = p_param;

  return val;
end;



Я пробовал на DEV среде вызывать функцию:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
declare
  param varchar2(100);
  val varchar2(100);
begin
  for i in 1..100000 loop
    val := get_parameter(param);
  end loop;
end;


С функцией тоже все работает.

После того, как выполнили ALTER TABLE на проде, я начал мониторить, есть ли какой-то результат или нет.
Сначала проверил через час после выполнения скрипта. Эффекта никакого. Снижения нагрузки на проц нет, в V$RESULT_CACHE_OBJECTS пусто. Проверил через сутки. То же самое. Потом на пару недель забросил это дело, занимался другими вещами. А когда вернулся к этой таблице опять, оказалось, что кэширование результата работает, но как-то неравномерно. Время от времени кто-то обновляет таблицу параметров, из-за чего кэш инвалидируется на какое-то время, а потом опять начинает работать. Ну то есть таблица была обновлена утром в районе 7 часов, запись в V$RESULT_CACHE_OBJECTS появилась в 12:40, запросы выполняются все время без перерыва.
То есть на DEV среде данные начинают кэшироваться сразу, а на проде - через какой-то довольно длительный интервал.
Почему так? Чего ораклу не хватает?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134070
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич

Есть таблица параметров. В ней примерно 400 строк.

И Вы пытаетесь ускорить точечный запрос к такой таблице? Он же и так должен "летать"

Код: plsql
1.
2.
3.
4.
select parameter_value
      into val
      from parameter_table
     where parameter_name = param;


CREATE INDEX parameter_table_i1 on parameter_table(parameter_name,parameter_value)
IMHO

Никанор Кузьмич

Но на самом деле, приложение обращается к таблице не напрямую, а через функцию. То есть там что-то вроде

А почему не закешировать результат ф-ции?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134076
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич
Сначала я потренировался на DEV бд, как это работает. Сделал скрипт вроде такого:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
declare
  param varchar2(100);
  val varchar2(100);
begin
  for i in 1..100000 loop
    select parameter_value
      into val
      from parameter_table
     where parameter_name = param;
  end loop;
end;


В таком виде - работает хорошо, все ок.
После выполнения alter table parameter_table result_cache (mode force)
этот кусок кода работает в десятки раз быстрее, проц грузит меньше.
Проверял V$RESULT_CACHE_OBJECTS - там отображается мой запрос.

Вот прямо в таком виде и запускали?
И оно сработало 100 000 раз?

Но почему у вас нет обработчика исключительной ситуации NO_DATA_FOUND?

Приведите ТОЧНЫЙ код программы, который вы выполняли, а не ваши "вспышки памяти" об этом коде.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134077
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что показывает запрос:
Код: plsql
1.
SELECT name, display_value FROM V$SYSTEM_PARAMETER WHERE name LIKE 'result_cache%';   

?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134081
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
А почему не закешировать результат ф-ции?
Можно, но проблема в том, что функцию надо перекомпилировать для этого. А клиентских приложений у БД много, многие работают 24х7, то есть нужно выделить окно, всех оповестить, потом отключить, перекомпилировать, потом всех включить обратно. А тут просто одну строчку выполнить и всё.
и все это накладывается на бардак в процессах разработки и деплоя, а также на отсутствие трети команды разработки. Потому что верхние рукамиводители сказали, что оракл - это дорого, поэтому мы с него будем уходить. 4 из 11 девелоперов на следующий день встали и ушли. А мне теперь разгребать.

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

Leonid Kudryavtsev
И Вы пытаетесь ускорить точечный запрос к такой таблице? Он же и так должен "летать"
А он и летает - просто низенько... См. ниже скриншот - два отчета за сутки, когда работало и когда нет. 9,5 мс на запрос до против 0,4 на запрос после.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134083
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич
в процессах разработки и деплоя, а также на отсутствие трети команды разработки.
Потому что верхние рукамиводители сказали, что оракл - это дорого, поэтому мы с него будем уходить.
4 из 11 девелоперов на следующий день встали и ушли. А мне теперь разгребать.

Зато вам теперь будут платить зарплату минимум за двоих!
Разве нет?

Начальственные иномарки ваша контора теперь же тоже заменяет на изделия отечественного автопрома!?
Разве нет?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134084
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич
См. ниже скриншот - два отчета за сутки, когда работало и когда нет.
9,5 мс на запрос до против 0,4 на запрос после.

Зачем вы показываете разные отчеты?
Покажите одинаковые отчеты.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134087
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus
Но почему у вас нет обработчика исключительной ситуации NO_DATA_FOUND?
Я исходил из предположения, что в реальных условиях приложение запрашивает только существующие в таблице параметры.

SQL*Plus
Приведите ТОЧНЫЙ код программы, который вы выполняли, а не ваши "вспышки памяти" об этом коде.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
declare
  type s is table of varchar2(4000);
  p_list s;
  v_value varchar2(4000);
  t timestamp := systimestamp;
  c number;
begin
  execute immediate 'alter table version_parameter result_cache (mode force)';
  select /*+ NO_RESULT_CACHE */ distinct vepa_par_name
    bulk collect into p_list
    from version_parameter;

  c := p_list.count;
  
  for i in 1..100000 loop
    select max(vepa_par_value)
      into v_value
      from ( select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username
              order by vepa_usr_name, vepa_vers_key)
     where rownum = 1;
  end loop;
  dbms_output.put_line(systimestamp - t);
  execute immediate 'alter table version_parameter result_cache (mode default)';
end;
/
...
Рейтинг: 0 / 0
Как работает result cache
    #40134089
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus
Зато вам теперь будут платить зарплату минимум за двоих!
Разве нет?
Че-то не торопятся. Но было бы неплохо

SQL*Plus
Начальственные иномарки ваша контора теперь же тоже заменяет на изделия отечественного автопрома!?
Разве нет?
Здесь немного другое "отечество". С каким надо автопромом И об иномарках для себя начальство уже позаботилось. А вот разработка хромает, да.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134173
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username
              order by vepa_usr_name, vepa_vers_key)
     where rownum = 1;



1. Лично я бы, предложил отложить result cache в сторону и начать с начала.
С реального запроса и реального плана его выполнения.
Построить индекс включающий все необходимые поля, что бы данные брались только из индекса
( vers_company, vepa_par_name, vapa_usr_name, vepa_vers_key, vepa_par_value )
совсем желательно, построить такой индекс, что бы и сортировка из плана исчезла

2. Если я правильно понимаю логику, то result cache'у придется заполняться для каждого пользователя отдельно . Т.е. практический эффект будет только когда все пользователи войдут в систему, т.е. только при их 2-ом и последующих входах. Объем получившегося кэша мне вообще представить сложно. Если система настолько высоконагружена, то можно предположить, что и разных пользователей там много. Т.е. кол-во записей в кэше будет намного больше исходной таблицы (примерно 400 строк). Смысл такой "оптимизации" мне не совсем очевиден.

IMHO могу быть не прав
...
Рейтинг: 0 / 0
Как работает result cache
    #40134179
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Никанор Кузьмич

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username
              order by vepa_usr_name, vepa_vers_key)
     where rownum = 1;



1. Лично я бы, предложил отложить result cache в сторону и начать с начала.
С реального запроса и реального плана его выполнения.
Построить индекс включающий все необходимые поля, что бы данные брались только из индекса
( vers_company, vepa_par_name, vapa_usr_name, vepa_vers_key, vepa_par_value )
совсем желательно, построить такой индекс, что бы и сортировка из плана исчезла

2. Если я правильно понимаю логику, то result cache'у придется заполняться для каждого пользователя отдельно . Т.е. практический эффект будет только когда все пользователи войдут в систему, т.е. только при их 2-ом и последующих входах. Объем получившегося кэша мне вообще представить сложно. Если система настолько высоконагружена, то можно предположить, что и разных пользователей там много. Т.е. кол-во записей в кэше будет намного больше исходной таблицы (примерно 400 строк). Смысл такой "оптимизации" мне не совсем очевиден.

IMHO могу быть не прав


мне казалось кэш общий.. но вообще странно с нагрузкой на проц бороться кешированием. Согласен что надо смотреть на план.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134184
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbi

мне казалось кэш общий..

не очень понимаю, смысл слова "общий". вообще про кэш в Oracle знаю мало (но на моих ф-циях - все нормально работает)

но запрос-то отбирается данные в зависимости от user_name, т.е. если поменялся user_name, запрос все равно перевыполнить придется. Т.е. нам надо count(user_name) * count(paramenter_name) записей в кэше. При большом кол-ве различных user_name, это может оказаться значительно больше исходных 400 строк.

IMHO могу ошибаться
...
Рейтинг: 0 / 0
Как работает result cache
    #40134186
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus
Что показывает запрос:
Код: plsql
1.
SELECT name, display_value FROM V$SYSTEM_PARAMETER WHERE name LIKE 'result_cache%';   


?
Черт, я был уверен, что приложил результат еще вчера, но он потерялся где-то по дороге.
Код: plsql
1.
2.
3.
4.
5.
6.
NAME                               DISPLAY_VALUE
---------------------------------- ------------------
result_cache_mode                  MANUAL
result_cache_max_size              83904K
result_cache_max_result            5
result_cache_remote_expiration     0




Leonid Kudryavtsev
Если я правильно понимаю логику, то result cache'у придется заполняться для каждого пользователя отдельно . Т.е. практический эффект будет только когда все пользователи войдут в систему, т.е. только при их 2-ом и последующих входах.
Я тут работаю недавно, пока не в курсе всего зоопарка. Насколько я понимаю, есть некоторое количество приложений, которые работают каждое от своего пользователя, и вот одно из них и спамит. Нагрузка достаточно равномерная, порядка 10 запросов в секунду, так что второго входа после первого ждать недолго.

Leonid Kudryavtsev
Объем получившегося кэша мне вообще представить сложно. Если система настолько высоконагружена, то можно предположить, что и разных пользователей там много. Т.е. кол-во записей в кэше будет намного больше исходной таблицы (примерно 400 строк). Смысл такой "оптимизации" мне не совсем очевиден.
V$RESULT_CACHE_OBJECTS обычно показывает 5 - 7 записей для этого запроса. Терпимо.

Но, вообще говоря, мой вопрос был скорее теоретический о тонкостях работы кэша, а ситуация приведена только в качестве примера.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134196
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Melkomyagkii_newbi

мне казалось кэш общий..

не очень понимаю, смысл слова "общий". вообще про кэш в Oracle знаю мало (но на моих ф-циях - все нормально работает)

но запрос-то отбирается данные в зависимости от user_name, т.е. если поменялся user_name, запрос все равно перевыполнить придется. Т.е. нам надо count(user_name) * count(paramenter_name) записей в кэше. При большом кол-ве различных user_name, это может оказаться значительно больше исходных 400 строк.

IMHO могу ошибаться


да, не обратил внимания на запрос ТС, думал вы описали особенность самого result cache.

Никанор Кузьмич, возможно у запросов есть несколько чаилд курсоров и они долго переключаются между вариантом с кэшем и без? Ну и мне до сих пор не очень понятно как result cache помогает cpu экономить для простой выборки(без агрегатов и прочих вычислений)
...
Рейтинг: 0 / 0
Как работает result cache
    #40134218
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич
SQL*Plus
Что показывает запрос:
Код: plsql
1.
SELECT name, display_value FROM V$SYSTEM_PARAMETER WHERE name LIKE 'result_cache%';   


?
Черт, я был уверен, что приложил результат еще вчера, но он потерялся где-то по дороге.
Код: plsql
1.
2.
3.
4.
5.
6.
NAME                               DISPLAY_VALUE
---------------------------------- ------------------
result_cache_mode                  MANUAL
result_cache_max_size              83904K
result_cache_max_result            5
result_cache_remote_expiration     0


Максимальный размер Result Cache = 80 МБ.
На один результат не более 5%. 80 МБ * 5% = 4 МБ.
Не так уж много, но для вашей таблички должно было хватить.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134227
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Никанор Кузьмич

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username
              order by vepa_usr_name, vepa_vers_key)
     where rownum = 1;



1. Лично я бы, предложил отложить result cache в сторону и начать с начала .
С реального запроса и реального плана его выполнения.
Построить индекс включающий все необходимые поля, что бы данные брались только из индекса
( vers_company, vepa_par_name, vapa_usr_name, vepa_vers_key, vepa_par_value )
совсем желательно, построить такой индекс, что бы и сортировка из плана исчезла
Это хорошее предложение.

Leonid Kudryavtsev

2. Если я правильно понимаю логику, то result cache'у придется заполняться для каждого пользователя отдельно . Т.е. практический эффект будет только когда все пользователи войдут в систему, т.е. только при их 2-ом и последующих входах. Объем получившегося кэша мне вообще представить сложно. Если система настолько высоконагружена, то можно предположить, что и разных пользователей там много. Т.е. кол-во записей в кэше будет намного больше исходной таблицы (примерно 400 строк). Смысл такой "оптимизации" мне не совсем очевиден.

IMHO могу быть не прав

Нет, Result Cache один на все сессии.
Вы же знаете, что разные сессии используют одни и те же курсоры для одинаковых команд.

То же самое и с Result Cache: используется для одинаковых команд с одинаковыми значениями Bind Variables.
На каждое сочетание значений Bind Variables имеется один результат в этом кэше.

Причем, если для данного сочетания ничего не возвращается, то для него все равно хранится информация "ничего не выбрано".
Бывает, что такими "ничего не выбрано" заполняется почти все пространство кэша.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134236
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbi
Ну и мне до сих пор не очень понятно как result cache помогает cpu экономить для простой выборки (без агрегатов и прочих вычислений)

Таблицу умножения с помощью Result Cache оптимизировать не удаётся.
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
SQL> SET SERVEROUTPUT ON;
SQL> 
SQL> DECLARE
  2     ln_hsec NUMBER;
  3     k_max PLS_INTEGER := 1E+4;
  4     ln_res NUMBER;
  5  BEGIN
  6     ln_hsec := dbms_utility.get_time;
  7  <<L0>>
  8     FOR k IN 1 .. k_max LOOP
  9  <<L1>>
 10        FOR m IN 1 .. 9 LOOP
 11  <<L2>>
 12           FOR n IN 1 .. 9 LOOP
 13              SELECT m * n INTO ln_res FROM dual;
 14           END LOOP L3;
 15        END LOOP L2;
 16     END LOOP L0;
 17     ln_hsec := dbms_utility.get_time - ln_hsec;
 18     dbms_output.put_line('ln_hsec = ' || ln_hsec);
 19  END;
 20  /
ln_hsec = 595

PL/SQL procedure successfully completed.

SQL> DECLARE
  2     ln_hsec NUMBER;
  3     k_max PLS_INTEGER := 1E+4;
  4     ln_res NUMBER;
  5  BEGIN
  6     ln_hsec := dbms_utility.get_time;
  7  <<L0>>
  8     FOR k IN 1 .. k_max LOOP
  9  <<L1>>
 10        FOR m IN 1 .. 9 LOOP
 11  <<L2>>
 12           FOR n IN 1 .. 9 LOOP
 13              SELECT /*+ RESULT_CACHE */ m * n INTO ln_res FROM dual;
 14           END LOOP L3;
 15        END LOOP L2;
 16     END LOOP L0;
 17     ln_hsec := dbms_utility.get_time - ln_hsec;
 18     dbms_output.put_line('ln_hsec = ' || ln_hsec);
 19  END;
 20  /
ln_hsec = 753

PL/SQL procedure successfully completed.



Без Result Cache 5,95 секунды,
а с Result Cache 7.53 секунды.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134242
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Для более сложных вычисляемых выражений ускорение есть.
LN( SQRT(m * n) )
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
SQL> SET ECHO ON;
SQL> SET SERVEROUTPUT ON;

SQL> DECLARE
  2     ln_hsec NUMBER;
  3     k_max PLS_INTEGER := 1E+4;
  4     ln_res NUMBER;
  5  BEGIN
  6     ln_hsec := dbms_utility.get_time;
  7  <<L0>>
  8     FOR k IN 1 .. k_max LOOP
  9  <<L1>>
 10        FOR m IN 1 .. 9 LOOP
 11  <<L2>>
 12           FOR n IN 1 .. 9 LOOP
 13              SELECT LN(SQRT(m * n)) INTO ln_res FROM dual;
 14           END LOOP L3;
 15        END LOOP L2;
 16     END LOOP L0;
 17     ln_hsec := dbms_utility.get_time - ln_hsec;
 18     dbms_output.put_line('ln_hsec = ' || ln_hsec);
 19  END;
 20  /
ln_hsec = 1748

PL/SQL procedure successfully completed.

SQL> DECLARE
  2     ln_hsec NUMBER;
  3     k_max PLS_INTEGER := 1E+4;
  4     ln_res NUMBER;
  5  BEGIN
  6     ln_hsec := dbms_utility.get_time;
  7  <<L0>>
  8     FOR k IN 1 .. k_max LOOP
  9  <<L1>>
 10        FOR m IN 1 .. 9 LOOP
 11  <<L2>>
 12           FOR n IN 1 .. 9 LOOP
 13              SELECT /*+ RESULT_CACHE */ LN(SQRT(m * n)) INTO ln_res FROM dual;
 14           END LOOP L3;
 15        END LOOP L2;
 16     END LOOP L0;
 17     ln_hsec := dbms_utility.get_time - ln_hsec;
 18     dbms_output.put_line('ln_hsec = ' || ln_hsec);
 19  END;
 20  /
ln_hsec = 772

PL/SQL procedure successfully completed.


без кэша - 17.48 с
с кэшем - 7.72 с
...
Рейтинг: 0 / 0
Как работает result cache
    #40134245
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus
Для более сложных вычисляемых выражений ускорение есть.


Логично, я про то и говорю - странно на обычном запросе экономить cpu с помощью кеширования. Выбрать из shared пула будет менее cpu intensive чем с buffer cache?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134296
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич,

Что возвращает такой запрос
Код: plsql
1.
SELECT dbms_result_cache.status() FROM dual;

?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134301
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SQL*Plus,

Возвращает ENABLED.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134323
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич
То есть на DEV среде данные начинают кэшироваться сразу,
а на проде - через какой-то довольно длительный интервал.
Почему так? Чего ораклу не хватает?


Сравните версии Oracle Database.
Код: plsql
1.
SELECT * FROM v$version;


Они одинаковые?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134338
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обе одинаковые - 12.1.0.2.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134388
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич,

Сколько тебе написали советов, но, к сожалению, именно по теме alter table ... result_cache (mode force) ничего.
Это не самая стабильно работающая вещь в oracle и если хочешь досконально разобраться иди на metalink и/или создавай запросы к поддержке.

Самое лучшее - ручками задать result_cache для запросов или получать данные вызовом функций с result_cache.
Если такое возможно, естественно.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134416
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|
Сколько тебе написали советов, но, к сожалению, именно по теме alter table ... result_cache (mode force) ничего.
Я так понимаю, тут в принципе не так уж и много сказать можно. Вроде, по всему получается, что всё должно работать. У меня проблема усугубляется еще и тем, что я не знаю толком, кто, откуда и с какими параметрами вызывает функцию. Я еще немного понаблюдал сегодня, и складывается смутное подозрение, что проблема не в оракле, а в функции и в приложении, которое ее вызывает. Может, когда-нибудь доберусь до туда.

AlexFF__|
Это не самая стабильно работающая вещь в oracle

Да? Не могу сказать, что много пользовался этой фичей, но вроде до этого она не выглядела нестабильной.

В общем, всем спасибо за участие и поддержку :)
...
Рейтинг: 0 / 0
Как работает result cache
    #40134420
Вопрошатель
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Melkomyagkii_newbi
мне до сих пор не очень понятно как result cache помогает cpu экономить для простой выборки(без агрегатов и прочих вычислений)

подумалось.

у нас была проблема когда сотни сессий дергают маленькую справочную таблицу десятки раз в секунду каждая. Блок горячий, как следствие - cache buffer chain latch. result_cache можно было бы рассмотреть как вариант решения?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134450
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрошатель,

1) Есть "веками" устоявшее поверье - даже не пытайся задумываться, не дергать ли тебе за усы новую фичу,
если ей меньше трех поколений в твоей версии СУБД.


2) Ты просто заменишь один латч на другой. На старых версиях (вплоть до 12.1), почти наверно ситуацию ухудшишь.
Может быть и существенно, гораздо хуже, чем те игрушечные вдвое, которые показывались в предыдущих постах.

3) есть вещи, которые в кармане разработчика в качестве его повседневного рабочего инструмента.
Result_cache к ним не относится. Эта штуковина - игрушка в руках "архитектора" и/или администратора.
Когда им понадобится угробить или украсить бантиком свою систему - они тебе об этом, несомненно немедленно доложат.

Так что, если у тебя версия, как у Никанора Кузьмича - кури себе спокойно, не марай форум буквами, и себе не морочь голову.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134455
Melkomyagkii_newbi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрошатель
Melkomyagkii_newbi
мне до сих пор не очень понятно как result cache помогает cpu экономить для простой выборки(без агрегатов и прочих вычислений)

подумалось.

у нас была проблема когда сотни сессий дергают маленькую справочную таблицу десятки раз в секунду каждая. Блок горячий, как следствие - cache buffer chain latch. result_cache можно было бы рассмотреть как вариант решения?


скорее нет, чем да. мы самодельным кешем на pl/sql(в pga) решали подобное.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134536
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby

3) есть вещи, которые в кармане разработчика в качестве его повседневного рабочего инструмента.
Result_cache к ним не относится.

В текущей системе уже два раз сталкивался с ситуацией, когда без result_cache на ф-цию - даже не знаю, как бы "взлетело".

Понятно, что проблема в структуре данных и алгоритме, но переписывать алгоритм - практически не возможно (т.к. был написан давно и многие ньансы работы уже утеряны, лучше не трогать), менять структуру данных или придумывать какие ни будь mat view и триггеры - еще худшая "затычка", чем result cache

Т.ч. IMHO вполне рабочий инструмент, который в ряде случаях может помочь. Но разумеется, использовать его везде где только можно, лишь бы впихнуть новую фичу - не стоит.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134585
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev

...
Понятно, что проблема в структуре данных и алгоритме, но переписывать алгоритм - практически не возможно (т.к. был написан давно и многие ньансы работы уже утеряны, лучше не трогать), менять структуру данных или придумывать какие ни будь mat view и триггеры - еще худшая "затычка", чем result cache

...

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

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

вот запрос из этого топика:

Код: plsql
1.
2.
3.
4.
5.
6.
select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username



Он почти наверно "не настоящий", но, допустим, что именно вот такой точно и есть.

Вот это что за "радость":
Код: plsql
1.
2.
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username


И сколько раз вызывается username за время одного запроса?
Как точно выглядит этот распрекрасный username?

И как, по мнению топикстартера, должна обходиться система при построении кеша и поиске в нем, именно с этим фрагментом?
Мне лень изучать вопрос о точном устройстве result_cache, но на глаз это просто красные чернила вообще, и муть малопонятная
при попытке кеширования.
Для того, чтобы хотя бы приблизительно догадаться, какие у этого всего надежды, хотелось бы видеть саму функцию.

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

PS
Мы еще не спросили - а сам-то запрос - напрямую с клиента отдается, или вызывается внутри функции?
Если в функции, то почему она так часто зовется? И точно не в составе фильтра другого запроса?
...
Рейтинг: 0 / 0
Как работает result cache
    #40134596
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Биллинговая система раньше считала только дома, теперь пришлось считать и квартиры.

Хранение информации об атрибутах - достаточно сложное (версионность, историчность и прочее). В общем, обращение достаточно медленное.

Собственно ф-ция расчета вызывается для каждого расчитываемого объекта, в ней нужно получить все параметры квартиры + параметры здания + параметры всех квартир в здании. Вызывается столько раз, сколько квартир в доме. Параметры конкретной квартиры, вообще в результате получаются "кол-во квартир" * "кол-во квартир" раз.

понятно, что по хорошему нужно было бы:
1. Получить параметры дома, получить параметры всех квартир. Где-то сохранить
2. На основе этих параметров уже считать квартиры в конкретном здании
Но существующий вызывающий код, так "сортировать" задание на расчет не умеет. Изменить вызывающий код - очень сложно (опасно поломать). Result_cache как манна небесная.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134609
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev,

нет, это не понятно.
Вполне может быть, что именно в описанной сказке просто deterministic оказался бы в число раз атрибутов фееричнее.

Это даже, если про старые добрые временные таблицы не вспоминать, или pivot с no_merge.
Так - то моргающих лампочек много на ёлках. не обязательно последняя к ней прикрученная самая красивая.

PS
Про "атрибуты" я бы тоже мог достойный хорошего стендапа монолог сварганить.
Но, на сегодня и так план уже перевыполнен.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134618
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Ну, а если вас с десяток таких образованных, что будет со всеми вами одновременно делать вменяемый администратор?
Ну да, для dba все разрабы - козлы. Плохо, что у него нет зеркала.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134620
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Result_cache как манна небесная.
Result_cache следует использовать тогда, когда заранее прогнозируемо конечное (относительное малое) количество наборов входных аргументов за определённый промежуток времени.
В описанном тобой случае Result_cache, по сути, вреден, потому что входная мощность постоянно вытесняет кэш.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134626
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic
booby
Ну, а если вас с десяток таких образованных, что будет со всеми вами одновременно делать вменяемый администратор?
Ну да, для dba все разрабы - козлы. Плохо, что у него нет зеркала.

не-не,
В зеркале все с рогами и копытами. Программисту такое состояние привычно и за счастье.
А дба, думаю, как-то от зеркала всё-таки полезно изолировать.
Он редко, но бывает и нужен и полезен.
Нормального дба нельзя приводить в неработоспособное состояние путем установки зеркала.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134650
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic
booby
Ну, а если вас с десяток таких образованных, что будет со всеми вами одновременно делать вменяемый администратор?
Ну да, для dba все разрабы - козлы. Плохо, что у него нет зеркала.

Нормальные разрабы понимают, что какие у них есть DBA, такие и есть, и других не будет.
Нормальные DBA понимают, что какие у них есть разрабы такие и есть, и других не будет.
Нормальные разрабы и DBA понимают, что какие у них есть юзеры такие и есть, и других не будет.
Нормальные юзеры хвалят / ругают разрабов, и не догадываются, что сущеcтвуют ещё какие-то DBA,
аналисты, тестеры, стейджеры, саппортёры и др. :-)
...
Рейтинг: 0 / 0
Как работает result cache
    #40134719
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Никанор Кузьмич,

посмотрите кино по ссылке, если не видели.
Там есть моменты спорные, но в интересующей вас части, скорее стоит глянуть.

https://habr.com/ru/company/oleg-bunin/blog/414401/
...
Рейтинг: 0 / 0
Как работает result cache
    #40134729
SQL*Plus
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
Никанор Кузьмич,

посмотрите кино по ссылке, если не видели.
Там есть моменты спорные, но в интересующей вас части, скорее стоит глянуть.

https://habr.com/ru/company/oleg-bunin/blog/414401/

Да, докладчик хороший, кино интересное, грамотное и сделано хорошо.
Присоединяюсь к рекомендации.
...
Рейтинг: 0 / 0
Как работает result cache
    #40134794
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
booby
1) Есть "веками" устоявшее поверье - даже не пытайся задумываться, не дергать ли тебе за усы новую фичу,
если ей меньше трех поколений в твоей версии СУБД.
Что значит "дергать за усы" в данном контексте? По-моему, наоборот, очевидно, что скорость исправления багов пропорциональна частоте попыток использования.

booby
Ни секунды не сомневаясь в гипотезе, можно предполагать, что на вопрос почему, будет дан ответ - потому что слишком часто вызывается, а на вопрос где - ответ окажется - в фильтре сложного запроса, или в сложном запросе с финальной сортировкой.
Сама проблема, вызванная данным запросом, относительно мала на фоне других проблем, поэтому всем в основном пофиг. Я пока не знаю точно, где функция вызывается. Я встречал ее в коде раньше, и большинство примеров использования не вызывали подозрений. Проверять ее использование внутри запроса как-то не приходило в голову. Вчера после вашего поста проверил - да, оказывается, есть пара мест, где она стоит в запросе в секции WHERE. Если повезет найти одно место, откуда она вызывается слишком часто,

booby
Мы еще не спросили - а сам-то запрос - напрямую с клиента отдается, или вызывается внутри функции?
Опять же, сейчас сложно сказать. Запрос в том виде, в каком он указан в AWR отчете, встречается в функции, которая используется очень много где. Поэтому функция первая под подозрением, но это не значит, что кто-то где-то не вызывает его напрямую в таком же виде.


booby
вот запрос из этого топика:

Код: plsql
1.
2.
3.
4.
5.
6.
select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
               from version_parameter
              where vers_company = 'ABC'
                and vepa_par_name = p_list(mod(i, c) + 1)
                -- username на следующей строке - это функция
                and nvl(vepa_usr_name, username) = username




Он почти наверно "не настоящий", но, допустим, что именно вот такой точно и есть.
Он совсем чуть-чуть не настоящий. Вместо ABC стоят другие три буквы, а p_list(mod(i, c) + 1) - это я так по очереди перебираю все возможные параметры, а в реальной функции там стоит просто переменная.

booby
Никанор Кузьмич,

посмотрите кино по ссылке, если не видели.
Там есть моменты спорные, но в интересующей вас части, скорее стоит глянуть.

https://habr.com/ru/company/oleg-bunin/blog/414401/
Спасибо, посмотрю.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135430
VDeltsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторselect max(vepa_par_value)
into v_value
from ( select rownum, vepa_par_value, vepa_usr_name, vepa_vers_key
from version_parameter
where vers_company = 'ABC'
and vepa_par_name = p_list(mod(i, c) + 1)
-- username на следующей строке - это функция
and nvl(vepa_usr_name, username) = username
order by vepa_usr_name, vepa_vers_key)
where rownum = 1;

Никанор Кузьмич, приведите лучше пример реальной функции, а не тестового запроса.
Желательно сразу скрипт структуры таблицы и insert (название параметров оставить как есть, значения можно поменять).


Во-первых поддерживаю создание индекса.
vers_company, vepa_par_name, vapa_usr_name, vepa_vers_key, vepa_par_value.

Хотя не уверен, что для 400 строк он даст результат. Так как индекс нужен, чтобы быстро найти блок данных в большой таблице. А если данных всего 400 строк и они влезают в 5-10 блоков по 8 кб, то особого толку не будет.

Второе - посмотрел бы на IOT (когда таблица - это индекс по первичному ключу). Но это тоже толк будет от силы раза в два.


Затем ИЗБАВИЛСЯ бы от функции nvl в запросе. Я не уверен, что nvl - это SQL-функция.
Если это функция PL/SQL, то происходит переключение контекста для каждой строки.
Во всяком случае проверить это.

Варианты замены на такие:
and COALESCE(vepa_usr_name, username) = username
and (vepa_usr_name is null or vepa_usr_name = username)
and case when vepa_usr_name is null then 1 when vepa_usr_name = username then 1 else 0 end =1

В последнем варианте строки вообще не будут сравниваться (так как в таблице строк всего 400, значит vepa_usr_name наверняка почти не заполнено).

Вот тут как раз пишут, что NVL — это функция PL/SQL, следовательно снова будет переключение контекстов. Поэтому ее следует заменить на COALESCE или оператор CASE.
https://habr.com/ru/post/124948/

Далее проверить, что vepa_usr_name вообще хоть где-то заполнено. Если оно везде пустое, то вообще убрать из условия.

Что значит "username на следующей строке - это функция"?
Это шутка или это реально функция, а не переменная ORACLE username?
Если это реально функция, то просто в начале своей функции считать значение этой функции в переменную varchar и использовать уже константу. Возможно проблема именно в этом.

Никакой result cache тут явно не нужен.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135432
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VDeltsov

Вот тут как раз пишут, что NVL — это функция PL/SQL, следовательно снова будет переключение контекстов. Поэтому ее следует заменить на COALESCE или оператор CASE.
https://habr.com/ru/post/124948/

Не читайте до обеда советских газет (С)
...
Рейтинг: 0 / 0
Как работает result cache
    #40135445
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexFF__|
VDeltsov

Вот тут как раз пишут, что NVL — это функция PL/SQL, следовательно снова будет переключение контекстов. Поэтому ее следует заменить на COALESCE или оператор CASE.
https://habr.com/ru/post/124948/

Не читайте до обеда советских газет (С)

это не "советские газеты", а "письмена на заборе".
---
2VDeltsov, исключение NVL с немалой вероятностью автоматически приведет к ухудшению производительности запроса.
Для компенсации сего обстоятельства, его может потребоваться после этого заметно визуально усложнить.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135448
VDeltsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Протестировал nvl в ORACLE 12 - разницы не увидел, видимо это уже исправили.
Раньше была рекомендация его не использовать.

А то, что автор увидел прирост производительности в результате кэширования -
это результат того, что перестала выполняться функция "USERNAME".

Поэтому скорее всего достаточно будет просто один раз её считать в начале процедуры.

Однако возможно, что дело не только в этой самой процедуре, но и в чудо функции "USERNAME".
Так что рекомендую эту чудо функцию тоже привести. Возможно она сама по себе тоже подтормаживает.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135454
booby
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VDeltsov

Раньше была рекомендация его не использовать.

такой универсальной рекомендации, без оговаривания точного контекста, не было никогда.
А для случая, аналогичному обсуждаемому запросу - рекомендовано использовать.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135480
Shtirlitz33
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NVL штука странная и ее по возможности лучше е использовать если в выражении есть функции так как она сначала вычислит ве значения и только потом будет сравнивать.

А по условию это значение может быть и не нужно.

Вот например
Код: plsql
1.
2.
3.
4.
5.
6.
7.
with function func(p_number in number) return number
is
begin
  dbms_output.put_line('p_number = ' || p_number);
  return p_number;
end;
  select 111 from dual where nvl(func(1), func(2)) = 1



Второе выполнение функции не нужно так как с первой части единица он мы сначала его вычислим и только потом отбросим как ненужное.
Простая замена на coalesce дает ускорение порой просто на том что не выполняем того что не нужно выполнять

Вот аутпут для обоих случаев вполне наглядно.

p_number = 1
p_number = 2
end of test nvl

p_number = 1
end of test coalesce
...
Рейтинг: 0 / 0
Как работает result cache
    #40135700
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Никанор Кузьмич
Есть Oracle 12.1
Скорее всего, у вас 12.1. 0.1 и вы нарвались на баг Bug 16301888 - A query with result cache annnotated table is not cached (Doc ID 16301888.8) (вкратце, там автоматически не инвалидировался курсор при alter table ...result_cache)

Вообще после
Никанор Кузьмич
Код: plsql
1.
alter table parameter_table result_cache (mode force);

у вас должен инвалидироваться курсор (v$sql.object_status должен стать INVALID_UNAUTH), а при последующем парсе в плане должна появиться строка "RESULT CACHE".
А лучше бы проапгрейдиться до 19, тогда у вас прямо в v$sql появится столбец RESULT_CACHE.

Если же надо протрейсить RC, то есть
Код: plsql
1.
alter session set events 'trace[Result_Cache] disk = highest';


пример трейса: https://gist.github.com/xtender/b3401a5118cd6898ddb8be2ad82acac9

В целом же, лучше не делать alter table result_cache force, а точечно втыкать result_cache в запросе или на функцию, причем все зависимости должны быть крайне редко изменяемыми, иначе помрете на RC латчах.
...
Рейтинг: 0 / 0
Как работает result cache
    #40135701
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Никанор Кузьмич
Код: plsql
1.
-- username на следующей строке - это функция

а тут учтите, что каждая такая функция в запросе и ее зависимости будет добавлена в зависимости... вы таким образом форсируете кучу промежуточных result_cache
...
Рейтинг: 0 / 0
Как работает result cache
    #40135702
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
простой пример
скрипт
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
drop table t1 purge;
drop table t2 purge;
drop function f1;
set echo on;
create table t1 as select level a, level b from dual connect by level<=100;
create table t2 as select level a, level b from dual connect by level<=100;
create function f1 return int as
   res int;
begin
   select count(*) into res from t2;
   return res;
end;
/
alter system flush shared_pool;

alter table t1 result_cache (mode force);
set feed on sql_id;
select count(*) cnt from t1 where f1>0;
def rc_sqlid = &_sql_id
col result_cache for a15;
select sql_id,child_number,plan_hash_value,invalidations,optimizer_env_hash_value,result_cache from v$sql s where sql_id='&rc_sqlid';
col PLAN_TABLE_OUTPUT for a120;
select t.* from v$sql s,table(dbms_xplan.display_cursor('&rc_sqlid',child_number)) t
where s.sql_id='&rc_sqlid';
col object_name new_val cache_id;
select object_name from v$sql_plan p where p.sql_id='&rc_sqlid' and operation='RESULT CACHE';
col name for a40;
col cache_id for a10;
col cache_key for a10;
select o.id,o.name, 
       d.*,
       do.cache_id, do.cache_key,do.object_no
from  v$result_cache_objects o
     ,v$result_cache_dependency d
     ,v$result_cache_objects do
where o.cache_id='&cache_id'
  and d.result_id=o.id
  and do.id = d.depend_id;
set echo off;

output
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
SQL> create table t1 as select level a, level b from dual connect by level<=100;

Table created.

SQL> create table t2 as select level a, level b from dual connect by level<=100;

Table created.

SQL> create function f1 return int as
  2     res int;
  3  begin
  4     select count(*) into res from t2;
  5     return res;
  6  end;
  7  /

Function created.

SQL> alter table t1 result_cache (mode force);

Table altered.

SQL> set feed on sql_id;
SQL> select count(*) cnt from t1 where f1>0;

       CNT
----------
       100

1 row selected.

SQL_ID: a9nyksby4dfqm
SQL> def rc_sqlid = &_sql_id
SQL> col result_cache for a15;
SQL> select sql_id,child_number,plan_hash_value,invalidations,optimizer_env_hash_value,result_cache from v$sql s where sql_id='&rc_sqlid';

SQL_ID        CHILD_NUMBER PLAN_HASH_VALUE INVALIDATIONS OPTIMIZER_ENV_HASH_VALUE RESULT_CACHE
------------- ------------ --------------- ------------- ------------------------ ---------------
a9nyksby4dfqm            0      4294799605             0               1605398594 Y

1 row selected.

SQL_ID: bf2z9mfkdwnb1
SQL> col PLAN_TABLE_OUTPUT for a120;
SQL> select t.* from v$sql s,table(dbms_xplan.display_cursor('&rc_sqlid',child_number)) t
  2  where s.sql_id='&rc_sqlid';

PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------
SQL_ID  a9nyksby4dfqm, child number 0
-------------------------------------
select count(*) cnt from t1 where f1>0

Plan hash value: 4294799605

-------------------------------------------------------------------------------------------
| Id  | Operation            | Name                       | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |                            |       |     3 (100)|          |
|   1 |  RESULT CACHE        | 0d95aym0kvw37casnbgjdnqzfh |     1 |            |          |
|   2 |   SORT AGGREGATE     |                            |     1 |            |          |
|*  3 |    FILTER            |                            |       |            |          |
|   4 |     TABLE ACCESS FULL| T1                         |   100 |     3   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   3 - filter("F1"()>0)

Result Cache Information (identified by operation id):
------------------------------------------------------

   1 -

SQL> col object_name new_val cache_id;
SQL> select object_name from v$sql_plan p where p.sql_id='&rc_sqlid' and operation='RESULT CACHE';

OBJECT_NAME
------------------------------
0d95aym0kvw37casnbgjdnqzfh

1 row selected.

SQL> col name for a40;
SQL> col cache_id for a10;
SQL> col cache_key for a10;
SQL> select o.id,o.name,
  2         d.*,
  3         do.cache_id, do.cache_key,do.object_no
  4  from  v$result_cache_objects o
  5       ,v$result_cache_dependency d
  6       ,v$result_cache_objects do
  7  where o.cache_id='&cache_id'
  8    and d.result_id=o.id
  9    and do.id = d.depend_id;

        ID NAME                                      RESULT_ID  DEPEND_ID  OBJECT_NO     CON_ID CACHE_ID   CACHE_KEY   OBJECT_NO
---------- ---------------------------------------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
        64 select count(*) cnt from t1 where f1>0           64         66      79027          3 XTENDER.T2 XTENDER.T2      79027
        64 select count(*) cnt from t1 where f1>0           64         95      79026          3 XTENDER.T1 XTENDER.T1      79026
        64 select count(*) cnt from t1 where f1>0           64         71      78995          3 XTENDER.F1 XTENDER.F1      78995

3 rows selected.

...
Рейтинг: 0 / 0
Как работает result cache
    #40135800
Никанор Кузьмич
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Sayan Malakshinov
Скорее всего, у вас 12.1. 0.1 и вы нарвались на баг Bug 16301888 - A query with result cache annnotated table is not cached (Doc ID 16301888.8) (вкратце, там автоматически не инвалидировался курсор при alter table ...result_cache)
Не, у нас версия 12.1.0.2. В ней пофиксили уже? Описание бага гляну тоже.

Sayan Malakshinov
А лучше бы проапгрейдиться до 19, тогда у вас прямо в v$sql появится столбец RESULT_CACHE.
Говорят, пробовали (до моего прихода). Одно из приложений не взлетело, решили остаться на 12-й.

Sayan Malakshinov
Никанор Кузьмич
Код: plsql
1.
-- username на следующей строке - это функция


а тут учтите, что каждая такая функция в запросе и ее зависимости будет добавлена в зависимости... вы таким образом форсируете кучу промежуточных result_cache
Да, я уже догадался. Но там вроде простая функция - она тупо возвращает значение переменной из другого пакета. И вообще таких пользователей в системе немного.
...
Рейтинг: 0 / 0
Как работает result cache
    #40136255
VDeltsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Никанор Кузьмич,

Это у Вас переключение контекста на каждую строку, раз используете функцию.
К тому же её результат непонятно как кэшировать, ведь в запросе неизвестно заранее, какой результат вернет функция.

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

Функции в условии where - это самая детская ошибка, которую можно совершить.

Жду результата теста.
...
Рейтинг: 0 / 0
50 сообщений из 50, показаны все 2 страниц
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Как работает result cache
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]