Oracle 11g ile birlikte Advanced Compression özeliği ile tanışmış olduk. Öncesinde kullanılan Basic compression metodu (bu yöntemde Oracle 9i’ den bu yana kullanılmaktadır) temelde compresiion yapıyor olsada bir çok noktada ihtiyaçlarımızı tam olarak karşılamıyor idi. Örneğin compress edilmiş olan bir tabloya tek tek yapılan insertler compress edilemiyor sonradan gelen bu veriler tablo içerisinde uncompress olarak tutuluyordu. 11g ile gelen Advanced Compression özelliği ile bu tarz eksikliklerde giderilmiş oldu.
Compression exadata için ayrıca değerlendirilmesi gereken bir konudur. Çünkü exadata kısmında Hybrid Columnar Compression başlığı altında incelenmesi gereken farklı bir teknoloji var. Bu konuyu tek başına özel olarak başka bir yazıda detaylandırıyor olacaz. Burada Exadata dışındaki tüm instance’ larda (Rac ve Single instance’ ları kastediyorum) advanced compressison denildiğinde ne anlıyoruz, bize sağladığı avantajlar nelerdir ve nasıl kullanabiliriz özetle bunlardan bahsediyor olacağız.
Ufak bir hatırlatma Advanced Compression için ayrı bir lisans gerekmektedir.
Oracle database’ inde tablo sıkıştırma mantığının altında yatan temelde yinelenen verilerin ortadan kaldırılarak verinin sıkıştırılması mantığına dayanmaktadır. Tekrar eden kayıtlar bloğun en başında bir sembol tablo içerisinde saklanır, sonrasında tekrarlanan tüm veriler için bu sembol tablosuna referans edilir.
Peki sadece tablolarımı compress ededebiliriz ? Hayır, tabloların yanısıra materialize views, partition tables(buradaki partitionların tamamı veya bir kısmı da yapılabilir) compress edilebilir.
Objeleri compress ederken ne tür opsiyonlarımız var ve bunları kullanmak istersek nasıl kullanabiliriz onlara bakalım ;
1 – COMPRESS : Bu sıkıştırma türü data warehouse sistemler için daha uygun olarak kabul edilir. Sıkıştırma tablo veya partitiona yapılan insertler için enable durumdadır.
2 – COMPRESS FOR OLTP : OLTP sistemler için önerilen compression methotudur. Bu opsiyon kullanıldığında da tüm DML işlemleri için sıkıştırma olanağı sağlar.
11gR1 de kullanılan compress for direct_load operations 11gR2 ile birlişkte deprecated olmuştur. Bu opsiyon 11gR1’ De data warehouse sistemler için kullanılması önerilen bir opsiyondu. Aynı şekilde compress for all operations opsiyonu da 11gR2 ile birlikte deprecated olan başka bir opsiyondur. Bu opsiyonun yerinede 11gR2 ile birlikte compress for oltp opsiyonu getirilmiştir.
LOB segmentler ile ilgili olarak, eğer tablolarınız LOB segment içeriyorsa LOB segment dışında kalan tablonuz daki diğer alanlar compress edilebilecektir. (Securefile olarak store eidlmiş olan olan LOB segmentler için farklı bir compressing yöntemi bulunmaktadır)
Yukarıda detaylarından bahsetmiş olduğumuz compress opsiyonlarını karşılaştırıp, aşağıdaki işlemler sonucunda sistemin bu durumdan nasıl etkileneceğine bakalım (responce sürelerine , segment size’ larına ve sisteme getireceği ek yükler vs) ;
Burada yapmış olduğumuz tüm testlerin sonuçları yazının en altında özet olarak bulabilirsiniz.
Testimizde kullanmak üzere aynı kolon yapılarına sahip sadece compress özellikleri farklı olan 3 tane tablo create edelim. (nocompress, compress ve compress for oltp)
CREATE TABLE tbl_noncompress
(
id NUMBER,
c1 VARCHAR2 (100),
c2 VARCHAR2 (100),
sdate DATE DEFAULT SYSDATE,
description VARCHAR2 (100)
);
CREATE TABLE tbl_compress
(
id NUMBER,
c1 VARCHAR2 (100),
c2 VARCHAR2 (100),
sdate DATE DEFAULT SYSDATE,
description VARCHAR2 (100)
)
COMPRESS;
CREATE TABLE tbl_compress_oltp
(
id NUMBER,
c1 VARCHAR2 (100),
c2 VARCHAR2 (100),
sdate DATE DEFAULT SYSDATE,
description VARCHAR2 (100)
)
COMPRESS FOR OLTP;
Bu üç tabloyada aynı insert cümleciği ile 1.000.000 kayıt insert etmeye çalışalım;
— compress edilmemiş olan tabloya insert ;
SQL> begin
for i in 1..1000000 loop
insert into tbl_noncompress values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 50 secs
— compress edilmiş olan tabloya insert ;
SQL> begin
for i in 1..1000000 loop
insert into tbl_compress values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 51 secs
— compress for oltp opsiyonu ile compress edilmiş olan tabloya insert ;
SQL> begin
for i in 1..1000000 loop
insert into tbl_compress_oltp values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 02:09 mins
Bu üç tablomusun size’ larına bakalım ;
SQL> select segment_name, bytes/1024/1024 MB from user_segments
SEGMENT_NAME MB
——————————————————————————— ———-
TBL_NONCOMPRESS 88
TBL_COMPRESS 80
TBL_COMPRESS_OLTP 14
3 rows selected.
Testin biraz daha anlamlı olması açısından tablolarımıza 10 milyon data daha insert edelim, sonrasında delete ve update sürelerine bakalım ;
SQL> begin
for i in 1..10000000 loop
insert into tbl_noncompress values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 08:36 mins
SQL> begin
for i in 1..10000000 loop
insert into tbl_compress values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 09:01 mins
SQL> begin
for i in 1..10000000 loop
insert into tbl_compress_oltp values(100,’Deneme’, ‘Compress Test ‘,sysdate,’Oracle 11gR2 Advanced Compress Testing’) ;
end loop;
commit;
end ;
PL/SQL procedure successfully completed.
Elapsed Time for Script Execution: 20:42 mins
Son durumda tablo size’ larımızdaki son durum ;
SQL> select segment_name, bytes/1024/1024 MB from user_segments
SEGMENT_NAME MB
——————————————————————————— ———-
TBL_NONCOMPRESS 922
TBL_COMPRESS 832
TBL_COMPRESS_OLTP 152
3 rows selected.
İnsert performanslarına bakıldığında compress edilmeyen tablo responce süresi bakımından daha performanslı gözükmektedir. Ancak compress for oltp ile sıkıştırılmış olan tablonun size’ ına baktığımızda da diğerlerine oranla hatırı sayılır bir şekilde fark olduğu gözlenmektedir.
Şimdi update sürelerine ve update boyunca ilgili session tarafından kullanılan CPU değerlerine bakalım ;
SQL> update tbl_noncompress set id = 200
11000000 rows updated.
SQL> commit
Commit complete.
Time End: 23.10.2013 14:30:50
Elapsed Time for Script Execution: 08:59 mins
SQL> update tbl_compress set id = 200
11000000 rows updated.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 06:59 mins
SQL> update tbl_compress_oltp set id = 200
11000000 rows updated.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 26:49 mins
Update performanslarına bakıldığında compress tablo üzerinde yapılan işlemler de nispeten daha kısa sürdüğü ve esasında oltp opsiyonu ile sıkıştırılmış olan tabloda yapılan update’ in ise çok daha uzun sürdüğü gözlenmektedir. OLTP opsiyonunun oltp sistemler için önerilmesinin nedeni tablo compress edildilden sonra tablo üzerinde yapılan tüm DML aktivitelerininde compress olarak devam ediyor olmasındandır. Dolayısıyla bu özellik unutulmamalıdır.
SQL> delete tbl_noncompress where rownum< 1000000
999999 rows deleted.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 58 secs
SQL> delete tbl_compress where rownum< 1000000
999999 rows deleted.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 53 secs
SQL> delete tbl_compress_oltp where rownum< 1000000
999999 rows deleted.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 01:18 min
1 milyon kaydı silmek istediğimiz deki süreler bu şekilde tabloyu tamamen delete komutu ile silmek istediğimizdeki süreler ise (test yaptığımız için truncate yapmıyoruz) ;
SQL> delete tbl_noncompress
10000001 rows deleted.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 14:06 mins
SQL> delete tbl_compress
10000001 rows deleted.
SQL> commit
Commit complete.
Elapsed Time for Script Execution: 07:52 mins
Time Start: 23.10.2013 15:54:44
SQL> delete tbl_compress_oltp
10000001 rows deleted.
SQL> commit
Commit complete.
Time End: 23.10.2013 16:06:21
Elapsed Time for Script Execution: 11:37 mins
Bu şekildede compress olan tablomuzun performansı diğerlerine göre daha iyi olduğunu söyleyebiliriz. Aynı şekilde compress for oltp opsiyonu ile sıkıştırılmış olan tablomusun performansı da nocompress olan tabloya göre nispeten daha iyi sonuç vermiştir.
Son olarak da select sürelerine bakalım, bu testmizde full table scan yaparak 3 tablomuzun toplam kayıt sayılarını sorgulayalım. (Test öncesinde her 3 tabloda yukarıdaki insert testinde kullanılan plsql yardımı ile 11 miyon kayıt içerek şekilde doldurulmuştur. )
Select performanslarına bakmadan önce her 3 tablo için execution planlarına bakalım isterseniz ;
Compress olmayan tablo üzerindeki sorgumuzun costu 31.860 ;
Compress olan tablo üzerindeki sorgumuzun costu 28.823 ;
Compress for oltp olan tablo üzerindeki sorgumuzun costu 5.304;
olarak gözüküyor. Bakalım bu costların select performansına yansıması nasıl ;
SQL> select count(*) from tbl_noncompress
COUNT(*)
———-
11000000
1 row selected.
Elapsed Time for Script Execution: 15 secs
SQL> select count(*) from tbl_compress
COUNT(*)
———-
11000000
1 row selected.
Elapsed Time for Script Execution: 13 secs
SQL> select count(*) from tbl_compress_oltp
COUNT(*)
———-
11000000
1 row selected.
Elapsed Time for Script Execution: 3 secs
Responce sürelerinden de anlaşılacağı üzere compress for oltp ile compress edilmiş olan tablo diğerlerine oranla çok daha iyi bir select performansı göstermektedir.
Yapmış olduğumuz tüm testlerin toplu olarak sonuçlarını aşağıdaki tabloda görebilirsiniz.
Amacınızın yer kazanmak olduğu veya birinci derecede kritik olmayan sistemler için oltp opsiyonu kullanılabilir bir opsiyondur. Özellikle history datasının yoğun tutulduğu tabloların olduğu sistemlerde compress for oltp özelliği kullanılabilir olarak göze çarpmaktadır.
Yukarıda örneğimizde tabloyu create ederken compression yaparak devam etmiştik. Peki var olan tablolar üzerinde bu çalışmayı yapmak istersek nasıl yapabiliriz ona bakalım ;
===> alter table test1 compress ;
Table altered.
===> alter table test1 compress for oltp ;
Table altered.
Compress edilmiş olan bir tabloyu uncompress etmek istersek ;
===> alter table test1 nocompress
Table altered.
===> alter table test2 nocompress
Table altered.
Tablomuz partitionlı ise nasıl compress edebiliriz ona bakalım ;
Alter table KAMIL.TEST1 modify partition SYS_P14538 COMPRESS FOR OLTP
Table altered.
Kimi tablolarınızda sayı itibariyle çok fazla partition olabilir o zamanda aşağıdaki sorgu yardımıyla compression komutunu otomatik olarak oluşturabilirsiniz;
SELECT ‘ alter table ‘ ||table_owner||’.’||table_name|| ‘ modify partition ‘ ||partition_name|| ‘ COMPRESS FOR OLTP ;’ FROM dba_tab_partitions where table_owner = ‘KAMIL’ and table_name like ‘TEST%’ ;
Compress olan partition alanlarımızı nasıl uncompress edebiliriz ;
Alter table KAMIL.TEST1 modify partition SYS_P14538 nocompress;
Table altered.
Partition alanlarından hangileri compress edilmiş diye bakmak istersek de ;
SELECT table_owner, table_name, partition_name, compression, compress_for
FROM dba_tab_partitions
where table_owner = ‘KAMIL’ ;
sorgusunu kullanabiliriz. Tabloların haricinde indexleri de aynı kapsamda compress hale getirebiliriz.
ALTER INDEX indx1 REBUILD COMPRESS;
Uncompress etmek için ;
ALTER INDEX indx1 REBUILD NOCOMPRESS;
Tablolarda olduğu indexleride create ederken compress yapabiliriz ;
CREATE INDEX indx2 ON TEST1 COMPRESS ;
Tabloyu partitionlarken partition bazında imi partitionların compress kimilerinde nocompress olacak şekilde set edebiliriz ;
CREATE INDEX indx3 ON test1 (id) COMPRESS LOCAL
(PARTITION id_old , PARTITION id_2003,
PARTITION id_new NOCOMPRESS);
Son olarak tablespace bazında compressing yapmak istersek, create ederken yapmak istersek;
CREATE TABLESPACE data DATAFILE
‘C:\ORACLE\ORADATA\TESTER\data01.DBF’ SIZE 1024M AUTOEXTEND ON NEXT 256M MAXSIZE 15360M
LOGGING
DEFAULT
COMPRESS FOR OLTP
EXTENT MANAGEMENT LOCAL AUTOALLOCATE
BLOCKSIZE 8K
SEGMENT SPACE MANAGEMENT AUTO
FLASHBACK ON;
Sonradan compress yapmak istersek ;
ALTER TABLESPACE DATA DEFAULT COMPRESS FOR OLTP;
Uncompress yapmak istersek ;
ALTER TABLESPACE DATA DEFAULT NOCOMPRESS;
Böylelikle compression ile ilgili sık kullanılabilecek olan komutların örnek scriptlerini de vermiş olduk.
Unutulmaması gereken bir nokta, hangi opsiyonu kullanmak isterseniz isteyin mutlaka öncesinde test etmeyi ihmal etmeyiniz.