Приклад застосування Result Cache на стороні сервера Oracle mechanics
Продуктивність СУБД та суміжні питання

Приклад застосування Result Cache на стороні сервера
Тема ненова, відноситься до «бородатих» нових фічів Oracle 11g, однак, технологія добре працює і, що важливо, що дозволяє за певних умов, суттєво економити ресурси сервера RDBMS
Практична частина
За умовчанням режим RESULT CACHE ручний (до 11.2.0.3 включно), регулюється параметромresult_cache_mode на рівні сесії/системи та/або підказкою/*+ RESULT_CACHE*/ на рівні запиту:
З AUTO option it decides if the result_cache потрібні для того, щоб бути сприятливим, спираючись на costing в oracle internal function. У цьому режимі рішення для використання result_cache is purely cost based
— гарно задумано — автоматичне включення кешування результатів запитів залежно від вартості виконання (CBO), також було б логічно враховувати частоту виконання запиту та частоту змін даних сегмента
Однак на практиці мені не вдалося змусити працювати кеш в автоматичному режимі, незважаючи на те, що план виконання рапортував про успішне застосування кешу:
Guys from Server Technologies хотіли б, щоб це було непрацездатним і неможливим було supported with 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, яка з'являється в плані виконання запиту з підказкоюRESULT_CACHE, абсолютно «прозора» —plan_hash_value не змінюється!):
— принаймні якщо судити за середнім часом виконання, при цьому статистика блоків BUFFER_GETS_PER_EXEC виглядає досить смішно — мабуть, через збіг plan_hash_value :)
Значне зменшення часу виконання підтверджується даними AWR
— запит пішов з 1-го місця в топі поDB Time, середній (Elap per exec ) та сумарний (Elapsed Time ) час виконання зменшився у 4- 5 разів за рахунок того, що лише один раз із чотирьох або п'яти запит справді змушений виконуватись через інвалідність кешу (змін даних). У тому ж звіті AWR з'являється характерне блокування/очікуванняenq: RC — Result Cache: Contention :
— із досить великим середнім часом
2,4 сек., і хоча очікувань таких чимало - 390 на 1401 виконання запиту (Executions ), час виконання запиту, що складається з часів процесора та очікування RC блокування:
у рази менше часу виконання того самого запиту без використання кешу. Максимальний час очікування від вже працюючого запиту готових результатів кешу результатів (enq:RC - Result Cache:Contention ) обмежено параметром:
— значення за промовчанням 10 секунд цілком розумне для запиту із середнім часом виконання 8 сек.
Зауваження та спостереження
1. Кеш результатів інвалідується при зміні будь-якої партиції таблиць, що використовуються в запиті, незалежно від того чи використовується ця партиція при виконанні запиту:
- кеш створений і успішно використовується для запиту, судячи з плану Oracle знає, що запит виконується використовуючи дані лише однієї партиції P001 таблиці XXX_TEST (PARTITION LIST SINGLE Pstart=1 Pstop=1 ), проте після зміни даних у партиції P002:
— судячи з ненульового значенняconsistent gets кеш не використовується, що точно відображено в оглядіV$RESULT_CACHE_OBJECTS :
- Старий кеш інвалідований (Invalid ), новий - створений (Published )
2. Інтенесним є кешування даних «віддалених» (реально або через loopback db link) таблиць/оглядів/матеріалізованих уявлень за допомогою параметраresult_cache_remote_expiration :
— за замовчуванням таке кешування вимкнено, при включенні результати запитів до «віддалених» об'єктів успішно кешуються незалежно від змін даних:
— після оновлення «віддаленої» таблиці/огляду результати запиту виходять з кешу — що видно за статистикоюconsistent gets, лічильникV$RESULT_CACHE_OBJECTS.SCAN_COUNT відповідно збільшився до 1
Принагідно варто відзначити, що використання кешу результатів (стимульоване підказкоюRESULT_CACHE ) не дозволяє керувати стороною db link'а, на якій буде виконуватися запит за допомогою показкиDRIVING_SITE.
Без використання кешу виконання запиту легко переноситься на далеку сторону лінка, стаючи повністю віддаленим (SELECT STATEMENT REMOTE з доступом долокальної таблиці XXX_T2 як до віддаленої - рядок 3):
Спроба використовувати кеш змінює план запиту на локальний з доступом до віддаленої таблиці (рядок 7 плану), що логічно з точки зору локального розміщення кешу:
Крім стандартних обмежень використання (точніше, невикористання) кешу результатів для запитів, що містять:
- Temporary or Dictionary tables
- Невизначені PL/SQL функції
- Sequence CURRVAL and NEXTVAL
- SQL функції CURRENT_DATE,SYSDATE,SYS_GUID, and so on
, кеш не застосовується при використанні в запитах будь-яких об'єктів (включаючи db link'і) із схем SYS та SYSTEM