Oracle Result Caching

Herkese Selam,

Bu yazıda sizlelerle, Oracle 11g ile dünyamıza giren  Result Caching mekanizmasını inceliyeceğiz.  (Result Caching özelliği Enterprise Edition ile kullanılabilmektedir.)

Caching, bilindiği üzere performans geliştirme amacı ile bilgisayar sistemlerinde sıkça kullanılan bir teknik. Bu teknik en basit hali ile, CPU’nun sık kullandığı bilgilerin kendisine  en yakın bellek birimine(Cache) getirilmesini öngören bir mekanizma olarak ifade edilebilir.  Oracle seviyesinde Result Caching’de bu alt yapı örnek alınarak geliştirilmiş bir performans geliştirme aracıdır. Oracle bu bağlamda, data dictinoary ile ilgili bilgileri dictionary cache’de cursor’larıda library cache’de tutarak performans arttırımını desteklemektedir.

 

Oracle 3 tip result cache yapısını desteklemektedir. Bunları sıra ile inceleyecek olursak;

1- Server Result Cache

2- Client Result Cache

3- PL/SQL Funcition Result Cache

 

SERVER RESULT CACHE

Adındanda anlaşılacağı gibi Oracle server tarafında var olan bir cache bölgesidir. Bu bölgede sorgularımızın döndürdüğü sonuçlar tutulmaktadır.

Result Cache’in başlıca motivasyonu birden çok kez çalıştırılan aynı sorguların tekrar tekrar execute edilmesini engellemektir. Böylelikle sorgu sonuçlarının, sorgu çalıştırılmadan hızlıca hafıza üzerinden döndürülmesi sağlanarak performans artışı hedeflenmiştir.

Result Cache Server’da shared pool’da bulunduğundan dolayı farklı sessionlarda çalıştırılan aynı sorgular içinde bu cache mekanizmasının kullanılması mümkün olmaktadır. Bu özellik db’ye eş zamanlı erişen  user sayısının fazla oldu Database sistemlerinde sorgu performansını pozitif şekilde  etkilemektedir.

Bind variable kullanılan sorgularda, variable parametresi her seferinde değişmesi muhtemel olduğundan, parametre değiştikçe üretilen result set , sorgu sonuçları farklı olması kaynaklı ayrı ayrı result cache’e alınırlar. Bind variable kullanırken result cache performansını gözlemleyebilmek istiyorsak aynı variable ile sorguyu çalıştırmamız yeterli olacaktır.

Temporary table’lar session bazlı işlem gören tablolar olduklarından dolayı cachelenmezler(https://emrahmete.wordpress.com/2012/02/19/oracle-global-temproray-tables/). Bunun yanı sıra deterministic olmayan fonksyon veya sequence’lere referans veren sorgularda cachelnmemektedirler. DB’de Read Consistency ilkesini tehlikeye atacak sorgular ve data dictionary view larını kullanan sorgularda cachelenmezler.

Şimdi bir örnek ile cache yapımızı nasıl kullanacağımızı ve çalışma zamanı farkına bir göz atalım.

SET TIMING ON

SELECT /*+result_cache*/
p.prod_category,
c.country_id,
SUM (s.quantity_sold) AS quantity_sold,
SUM (s.amount_sold) AS amount_sold
FROM sales s, customers c, products p
WHERE s.cust_id = c.cust_id AND s.prod_id = p.prod_id
GROUP BY p.prod_category, c.country_id
ORDER BY p.prod_category, c.country_id;

Elapsed: 00:00:07.98

Evet sorgumuzun sonucunun server tarafında cache’lenmesini istiyorsak sorgumuza yukarıdada anlaşılacağı gibi /*+result_cache*/ hintini veriyoruz. Sorgumuz ilk kez çalıştığında execution yapıldığından sorgu sonucumuz uzun sürmekte. Sorgu çalıştırılıp sonuç alındıktan sonra sorgu sonucu cache’de tutulmaya başlanmakta. Şimdi aynı sorguyu 2. kez çalıştırıp süre farkını inceleyelim.

SET TIMING ON

SELECT /*+result_cache*/
p.prod_category,
c.country_id,
SUM (s.quantity_sold) AS quantity_sold,
SUM (s.amount_sold) AS amount_sold
FROM sales s, customers c, products p
WHERE s.cust_id = c.cust_id AND s.prod_id = p.prod_id
GROUP BY p.prod_category, c.country_id
ORDER BY p.prod_category, c.country_id;

Elapsed: 00:00:00.23

Evet görüldüğü üzere sorgu sonucu cache’e alındıktan sonra sorgu sonucu  direk cache’den okunarak yeniden çalıştırılmadan döndürülmekte. Şimdi sorgumuzun execution planına bakalım.

EXPLAIN PLAN
FOR
SELECT /*+result_cache*/
p.prod_category,
c.country_id,
SUM (s.quantity_sold) AS quantity_sold,
SUM (s.amount_sold) AS amount_sold
FROM sales s, customers c, products p
WHERE s.cust_id = c.cust_id AND s.prod_id = p.prod_id
GROUP BY p.prod_category, c.country_id
ORDER BY p.prod_category, c.country_id;

 

set linesize 500
select * from table(dbms_xplan.display);

Evet sorgunun execution planını incelediğimizde 1 nolu adımda sonucun result cache’den okunacağına dair bir adım gözükmekte. Bu adımda Name kolonunda bulunan unique değer cache_id dir. Bu cache id yi alarak daha önce bu sorgunun kaç kez çalıştırıldığını ve diğer bilgilerini öğrenebiliriz.

SELECT status,
creation_timestamp,
build_time,
row_count,
scan_count
FROM v$result_cache_objects
WHERE cache_id = ‘4fq786v0sq49wgux1y518akv7q’;

 

CLIENT RESULT CACHE

Adından da analaşılacağı gibi sorgu sonuçlarının client tarafındaki cache bölgesinde tutulduğu cache mekanizmasıdır.

Client Result Cache’in en büyük avantajı server ile client arasındaki sorgu ve bunun karşılığında oluşan sonuç alışverişi yüzünden yaşanabilecek zaman kaybının olmamasıdır. Sorguda sonuçta client’da olduğundan işlem çok hızlı gerçekleşebilmektedir. Ancak bu sistemde birde çok büyük bir dez avantaj vardır. Cache’deki bilgi şayet geçerliliğini yitirmiş ise yani sorgu sonucu sorgu kaynağındaki tabloların dml alması ile değişmiş ise bu invalidasyonu anlamak için server’ı sürekli poll edecektir. Bu efektif bir yol değildir. Aynı zamanda result’ın client’da tutulması veri bütünlüğü anlamında sorgu sonucunun güncelliğinide garanti edememektedir.

client_result_cache_size parametresi ile aktive edilmektedir. Default’u sıfırdır yani disable’dır.Client cache’i kullanabilmek için bu parametreyi geçerli bir değer ile setlemek gerekmektedir.

 

PL/SQL Function Result Cache

PL/SQL Function Result Cache, Oracle Server da bulunan cache bölgesidir. Bu bölgede PL/SQL fonksyonlarının dönüş değerleri tutulmaktadır. Bu server side result cache ile farklı memory yapısını kullandığı fikrini akıllara getirilmemeli. İki cache yapısıda aynı memory yapısını kullanmaktadır.

Bu cache yöntemi ile aynı parametreler ile çalıştırılan fonksyonların döndürdüğü sonuçlar cache de saklanarak, tekrar aynı parametreler ile fonksyon çağırıldığında cache de bulunan sonuç fonksyon yeniden çalıştırılmadan kullanıcıya döndürülmektedir. Böylelikle yeniden execution yapılmaktan kaçınılarak hız ve performans kazancı sağlanmaktadır.

Şimdi bir örnek ile bu yapıyı açıklayalım.

CREATE OR REPLACE FUNCTION get_sales_total_for_customer (p_cust_id NUMBER)
RETURN NUMBER
RESULT_CACHE
IS
v_total NUMBER;
BEGIN
SELECT SUM (amount_sold)
INTO v_total
FROM sales
WHERE cust_id = p_cust_id;

RETURN v_total;
END get_sales_total_for_customer;
/
SET TIMING ON

DECLARE
v_total NUMBER;
BEGIN
v_total := get_sales_total_for_customer (2865);
DBMS_OUTPUT.put_line (v_total);
END;

PL/SQL Bloğu İlk çağırım —Elapsed: 00:00:01.09
PL/SQL Bloğu İkinci Çağrım — Elapsed: 00:00:00.04

 

Evet PL/SQL FUNCTION’ın döndüreceği sonucun cacheleneceğini yaratırken ifade ettik. Daha sonra fonksyonumuzu kullanan bir PL/SQL bloğu yazdığımızda aynı parametre ile 2. kez çağırdığımızda sonuç cache’den döndüğünden işlem çok hızlı gerçekleşmiştir.

PL/SQL Functions Result CAche için şunlar unutulmamalıdır.

– OUT veye IN OUT tipinde parametre alan fonksyonlar,

-Pipelined fonksyonlar

– Anonym pl/sql bloğu çağıran fonksyonlar

– LOB’s, REF CURSOR, Object veya Record tipinde değer döndüren fonksyonlar

Result Cache yapısı içerisinde kullanılamazlar. Bu istisnai durumlar haricinde yaratılan fonksyonlar cachelenere bu mekanizmadan faydalanabilir.

 

 

Kaynaklar: 

TroubleShooting Oracle Performance, Christian Antognini, 2008

http://www.oracle-developer.net/display.php?id=504

Advertisements

About ... from Emrah METE

Bilgisayar Mühendisi
This entry was posted in Oracle, Root, Uncategorized and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s