Пример за кеша на резултатите от сървъра, механика на Oracle
Производителност на СУБД и свързани проблеми

Темата не е нова, отнася се за "брадатите" нови функции на Oracle 11g, но технологията работи добре и, което е важно, позволява при определени условия значително да спести ресурсите на RDBMS сървъра
Практическа част
По подразбиране режимът RESULT CACHE е ръчен (до 11.2.0.3 включително), регулиран от параметъра резултат_кеш_режим на ниво сесия/система и/или подсказка / * + RESULT_CACHE * / на ниво заявка:
С опцията AUTO той решава дали result_cache трябва да бъде активиран въз основа на разходите във вътрешната функция на oracle. При този режим решението за използване на result_cache се основава чисто на разходите
- добре замислен - автоматично активиране на кеширането на резултатите от заявката в зависимост от цената на изпълнение (CBO), също така би било логично да се вземе предвид честотата на изпълнение на заявката и честотата на промените в данните за сегмента
На практика обаче не успях да накарам кеша да работи в автоматичен режим, въпреки факта, че планът за изпълнение отчита успешното използване на кеша:
Момчетата от Server Technologies ми казаха, че вероятно никога няма да работи и никога няма да бъде поддържано с AUTO
Неработоспособността на режим AUTO може да се види от общия преглед на системата V $ RESULT_CACHE_OBJECTS:
- странни стойности на броя зависимости, блокове, редове и др. Да се надяваме, че красотата на автоматичния режим може да бъде оценена в бъдеще (Oracle 12c?)
Ръчният режим работи добре:
- когато използвате подсказка RESULT_CACHE последващите изпълнения на заявката използват кеша, значително (до 0), намалявайки броя на четенията от буфера кеш (и физически четения, съответно) и времето за изпълнение - от 3 на 0,17 секунди.
Кешираните резултати заемат част от SGA - оттам се четат:
Освен това данните от проучването V $ RESULT_CACHE_OBJECTS за ръчен режим (SPACE = "SQL" - последен ред) изглежда много по-разумно, отколкото за автоматичен режим (SPACE = "AUTO" - предпоследен ред, първите три реда - зависимости от кеша):
Статистиката за изпълнение на заявките (в производствената база данни) с активиран кеш на ниво заявка стана значително по-добра (интересно е, че операцията КЕШ ЗА РЕЗУЛТАТИ, появява се в плана за изпълнение на заявката с подкана RESULT_CACHE абсолютно "прозрачен" - plan_hash_value не се променя!):
- поне, съдейки по средното време за изпълнение, статистиката на блоковете BUFFER_GETS_PER_EXEC изглежда доста забавна - очевидно поради съвпадението на plan_hash_value:)
Значително намаляване на времето за изпълнение се потвърждава от данните за AWR
- заявката премина от 1-во място в топ от DB Time, средното (Elap на изпълнител) и общо (Изминалото време) времето за изпълнение е намаляло с 4-5 пъти поради факта, че само веднъж от четири или пет заявки наистина са принудени да бъдат изпълнени поради анулиране на кеша (промени в данните). В същия доклад AWR се появява характерно блокиране/изчакване enq: RC - Кеш с резултати: Състезание:
- с достатъчно голямо средно време
2,4 секунди и въпреки че има много такива очаквания - 390 на 1401 изпълнения на заявки (Екзекуции), времето за изпълнение на заявката, обобщено времената на процесора и изчакване на RC заключване:
няколко пъти по-малко от времето за изпълнение на същата заявка без използване на кеша. Максималното време за изчакване от вече изпълнена заявка за резултати от кеша на готови резултати (enq: RC - Кеш с резултати: Състезание) ограничено от параметъра:
- стойността по подразбиране от 10 секунди е напълно разумна за заявка със средно време за изпълнение от 8 секунди.
Бележки и наблюдения
1. Кешът с резултати се обезсилва при промяна на който и да е дял от таблици, използвани в заявката, независимо дали този дял се използва при изпълнение на заявката:
- кешът е създаден и се използва успешно за заявката, съдейки по плана, Oracle знае, че заявката се изпълнява, използвайки данни само от един дял P001 на XXX_TEST (СПИСЪК НА ДЯЛИТЕ ЕДИНЕН Pstart = 1 Pstop = 1), но след промяна на данните в дял P002:
- съдейки по ненулевата стойност последователно получава кеш паметта не се използва, което е точно отразено в рецензията V $ RESULT_CACHE_OBJECTS:
- старият кеш е невалиден (Невалидно), ново - създадено (Публикувано)
2. Кеширане на данни на "отдалечени" (реални или чрез loopback db връзка) таблици/изгледи/материализирани изгледи с помощта на параметъра result_cache_remote_expiration:
- по подразбиране такова кеширане е деактивирано, когато е активирано, резултатите от заявките към "отдалечени" обекти се кешират успешно независимо от промените в данните:
- след актуализиране на "отдалечената" таблица/преглед, резултатите от заявката се получават от кеша - както се вижда от статистиката последователно получава, брояч V $ RESULT_CACHE_OBJECTS.SCAN_COUNT съответно се увеличава до 1
По пътя може да се отбележи, че използването на кеша за резултати (стимулирано от намека RESULT_CACHE) не ви позволява да контролирате страната на връзката db, на която ще бъде изпълнена заявката, като използвате подсказка DRIVING_SITE.
Без да се използва кеш, изпълнението на заявката лесно се прехвърля в далечната страна на връзката, като става напълно отдалечено (ИЗБЕРЕТЕ ИЗЯВЛЕНИЕ ДАЛЕНЕ с достъп до локалната таблица XXX_T2 като до отдалечена - ред 3):
Опитът за използване на кеша променя плана на заявката на локален с достъп до отдалечената таблица (ред 7 от плана), което е логично от гледна точка на локалното разпределение на кеша:
В допълнение към стандартните ограничения за използване (по-точно, да не се използва) кешът на резултатите за заявки, съдържащи:
- Временни или речникови таблици
- Недетерминирани PL/SQL функции
- Последователност CURRVAL и NEXTVAL
- SQL функции CURRENT_DATE, SYSDATE, SYS_GUID и т.н.
, кешът не се използва при използване на обекти (включително db връзки) от схемите SYS и SYSTEM в заявките