Про кешування результату PL / SQL-функції, Інші СУБД, Бази даних, статті

Всі найкращі практики та можливості надаються PL / SQL в Oracle Database 11g.Ви, скажімо, прочитали, що Oracle випустив одинадцятий реліз бази даних. Чудово! Але виникає проблема – ви не припускаєте її використання в найближчі два роки. А тому треба вам замислюватися про нові можливості в PL / SQL цієї версії? Подивимося на світ реально. Oracle виступив з новим релізом бази даних, і це означає, що його розробники ужсфокусіровани на цей нової реліз. Люди на зразок мене починають писати, демонструвати і навіть навчати цієї нової версії. А значить, є й інші: ті, хто залишається поки на більш старої версії, хто сподівається і молиться на те, що одного разу їх менеджмент може бути вважатиме за доцільне усунути цю невідповідність. Я поділяю ваші турботи. Я думаю і хочу сказати, що саме зараз має сенс вивчити ті можливості, які Oracle Database 11g запропонує вам і вашій компанії в майбутньому. Причина дуже проста: раз ви будете знати про можливості Ora-cle Database 11g, то ви, швидше за все, змініть метод написання коду вже зараз!

Скажімо, одна з найбільш важливих нових можливостей PL / SQL в Oracle Database 11g – це кешування результату PL / SQL-функції. Абсолютно неозвучена, проте, вельми відмінна можливість. У цій статті я пропоную короткий огляд і підведення підсумків обговорення, як знання цієї можливості може вплинути на написання PL / SQL-програм в більш ранніх версіях Oracle Database.


Припустимо, що я працюю в команді, яка створює додаток з обліку кадрів. Таблиця співробітників – одна з основних структур, що містить всі дані про всі співробітниках. Сотні користувачів виконують безліч запитів в додатку, який читає з цієї таблиці і читає дуже часто. Припустимо, що таблицю змінюють відносно рідко, приблизно один-два рази на годину. В результаті код програми періодично запитує блоки з буферного кешу, які в основному постійні, але виконує додаткову перевірку, щоб побачити, чи пройшов відповідний запит синтаксичний аналіз, розшукуючи дані в буфері і повертаючи їх. Команда повинна підвищити продуктивність запитів даних з таблиці Службовців (employees). В даний час використовується наступна функція, яка повертає рядок таблиці employees:


FUNCTION one_employee (employee_id_in
IN employees.employee_id%TYPE)
   RETURN employees%ROWTYPE
IS
    l_employee   employees%ROWTYPE;
BEGIN
   SELECT *
      INTO l_employee
      FROM employees
    WHERE employee_id = employee_id_in;
    RETURN l_employee;
EXCEPTION
    WHEN NO_DATA_FOUND
    THEN
       /* Return an empty record. */
       RETURN l_employee;
END one_employee;
Проте в Oracle Database 11g можна додати рядок в
заголовок цієї функції, як показано нижче:
 
FUNCTION one_employee (employee_id_in
IN employees.employee_id%TYPE)
   RETURN employees%ROWTYPE
   RESULT_CACHE RELIES_ON (employees)
IS
    l_employee   employees%ROWTYPE;
BEGIN
.


Вираз RESULT_CACHE говорить Oracle Data-base, що слід запам’ятовувати (зберігати в спеціальному буфері результатів оперативної пам’яті) кожний запис, витягнуту для зазначеного ID співробітника. І коли сесія виконує цю функцію і передає ID співробітника, який був збережений раніше, ядро ​​PL / SQL не виконує тіло функції, яке включає цей запит.


Замість цього просто витягується запис з кешу, і дані відразу ж повертаються. В результаті вилучення виконується набагато швидше.


Крім того, вказавши RELIES_ON (employees), ми інформуємо Oracle Database, що якщо якась із сесій зафіксує зміни в цій таблиці, всі дані в кеші результату, поміщені з таблиці, будуть інвалідними. Наступний виклик функції one_employee повинен буде виконати запит і отримати свіжі дані з таблиці. Так як кеш – це частина System Global Area (SGA), його вміст доступно всім сесіям, сполученим з примірником. Отже, Oracle Database буде застосовувати до кешу свій алгоритм LRU (“least recently used” – “заміщення найбільш давніх з використання даних”), щоб гарантувати, що найбільш часто запитувані дані будуть зберігатися в кеші. До Oracle Database 11g схожий вид кешування був можливий з колекціями рівня пакету, однак, цей кеш – сесійний і розташований в Process Global Area (PGA). Це означає, що, якщо є 1,000 різних сесій працюючого додатки, буде використовуватися величезна кількість пам’яті на додаток до того, що розміщено в SGA.


Кеш результату PL / SQL-функції мінімізує кількість пам’яті, необхідної для кешування, і робить ці дані загальними для всіх сесій. Це веде до зменшення використання пам’яті, плюс до автоматичної очищенні кеш результатів, коли б не виконалася фіксація зміни, що робить цю можливість Oracle Database 11g дуже корисною для оптимізації продуктивності PL / SQL-додатків. Аналіз продуктивності і вплив PGA Для тестування підвищення продуктивності та впливу пам’яті PGA при повторюваних запитів до даних, я розробив набір скриптів, доступних за посиланням otn.oracle.com/oramag/oracle/07-sep/o57plsql.zip, які порівнюють три різні способи вилучення рядків даних про співробітників:



Для самостійного тестування розпакуйте файл o57plsql.zip і виконайте скрипт 11g_emplu.tst. Він займе приблизно п’ять або шість секунд, і потім ви побачите приблизно такі результати:


PGA before tests are run:
session PGA:  910860 bytes
Execute query each time
Elapsed: 4.5 seconds.
session PGA:  910860 bytes
Cache table in PGA memory
Elapsed: .11 seconds.
session PGA: 1041932 bytes
Oracle Database 11g result cache
Elapsed: .27 seconds.
session PGA: 1041932 bytes


Наведу свої висновки на базі цього первісного, не зовсім повного експерименту:



Чому потрібно подбати вже зараз? “Добре”, – скажете ви собі. – “Класно! Але я не зможу використовувати ці можливості ще два роки або більше, що ж я можу зробити зараз?” У вас поки немає можливості використовувати кешування результату PL / SQL-функції, але вже зараз можна написати код так, що коли в кінцевому підсумку здійсниться перехід на Oracle Database 11g, у вас буде можливість швидко і легко використовувати кешування в коді програми. Іншими словами, уже зараз можна підготуватися до цієї майбутньої можливості. Як це зробити? Замініть всі запити (по крайней мере, до таблиць, які змінюються рідко, а запитуються часто) у внутрішніх функціях так, щоб можна було легко додати вираз RESULT_CACHE.


Подумайте про це: швидше за все сьогодні ви так не робите. Замість цього, при необхідності отримати дані з бази даних ви пишете необхідний запит безпосередньо в додатку (де б логіка ні розташовувалася, в серверній частині (в інших PL / SQL-програми) або на клієнті (в
програмах таких мов, як Java)).


І точно такий же запит (або його невелика варіація) буде з’являтися в різних місцях коду програми. Хіба ні? Так легше написати SQL-пропозиції; адже це одне з достоїнств PL / SQL. Однак, легкість використання при виконанні SQL всередині PL / SQL визнає SQL як
належне, а при переході на Oracle Database 11g ви за це розплачуєтеся.


Якщо після оновлення ви хочете отримати переваги RESULT_CACHE, необхідно буде знайти всі SQL-пропозиції, в кожному з них помістити підказку оптимізатора RESULT_CACHE (це нормально, така можливість доступна в SQL також, як і в функціях) або створити функцію, помістити в неї запит, знайти кожен відповідний запит програми та замінити запит на виклик функції.


Звичайно, по суті обидва ці підходи дублюють один одного, але зовсім не хочеться, щоб довелося їх застосовувати. IT-менеджери ненавидять вникати в існуючий, який працює виробничий код і “плутають карти “, постійно вносячи якісь зміни. Якщо зробити навпаки і почати прямо зараз в Oracle9i Database або Oracle Database 10g замінювати запити всередині функцій, ви будете майже відразу ж здатні перевести код на використання фантастичної можливості після переходу на Oracle Database 11g.


І, що найкраще, код програми, який викликає функцію, не повинен буде змінитися взагалі! Ваш менеджер буде дуже задоволений. Все це є приводом, щоб вивчати нові можливості Oracle Database 11g. Уже сьогодні!

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*