Uygulama Performans Optimizasyonu

Giriş

Küçük veya orta boyutlu QlikView uygulamalarında, performans açısından uygulamanın tasarımıyla ilgili endişe duymanız genellikle gerekmez. Uygulamanın tasarımı zayıfsa, veri miktarı arttıkça zaman ve bellek kısıtlamaları çok belirgin olabilir. Bazı basit tasarım değişiklikleri performansı ciddi oranda iyileştirebilir. Bu ek, birkaç yaygın hataya dikkat çekmekte ve bunlara çözümler sunmaktadır.

Genellikle, "sorun" uygulama nesnelerinden kod temelli veritabanına taşınarak performans iyileştirilir. Bu genellikle bir dengeleme durumudur. Yanıt süresi iyileştirilir ve geçici kabiliyet azaltılır. Aşağıdaki öneriler genel anlamda her durum için faydalı olarak algılanmamalıdır. Bu önerileri, uygulamanın genel durumunu iyileştirdiklerinde veya batma-çıkma durumları arasında ufak bir fark oluşturduklarında kullanın.

Yukarıda belirtilen sorunların ele alınması için uygulanan örnek yöntemlerin bir listesi aşağıda yer almaktadır. Bunlar, sorunu açıklamak ve faydalı QlikView özelliğine işaret etmek üzere hazırlanmıştır. Hangi yöntemin en iyi olduğuna dair genel bir öneri sunmak mümkün değildir; ancak örneklerin sıralaması bir gösterge olabilir.

Count (Distinct 'FieldName')

Count(distinct fieldname), özellikle test alanları için genel olarak performans tüketici bir işlemdir. Mümkün olduğunda, kod içinde okunduğu şekliyle her bir tekil oluşa '1' değeri atayarak, count() ve tekil niteleyiciyi sum() ile değiştirin.

Kod aşağıdaki gibi görünebilir:

Load

Alfa,

if (peek('Alfa')=Alfa,0,1) as Flag1,

Num

resident table_1

order by Alfa Asc;

Burada, "peek" öğesi, okunmakta olan Alfa'nın değerini daha önce okunanla karşılaştırır. Değerler aynıysa, "Bayrak" 0 olarak ayarlanır. Değerler farklıysa, "Bayrak" 1 olarak ayarlanır. Tekil değerlerin sayısı, böylece, sum(Flag) değerine eşit olur. Listenin sıralanması gerektiğini ve yükleme yerleşiğinde "order by" ifadesi kullanıldığında QlikView'ün okumaya başlamadan önce listeyi sıraladığını unutmayın.

Diğer bir yöntem:

Load distinct

Alfa,

Alfa as AlfaDist

resident table_1;

Artık Count(DistinctAlfa) basit bir sayımla yer değiştirilebilir: Count( AlfaDist ). Alfa'nın iki defa okunduğuna dikkat edin; bu öğe bir kez orijinal tabloya bağlamak için orijinal adla ve bir kez de Count() öğesine izin vermek için yeni bir adla okunur. (Count() içinde, alanların bağlanmasına izin verilmez). distinct cümlesinin derecesini azaltacağından, tüm diğer alanlar da dışarıda bırakılmalıdır. Üçüncü bir yöntem, "Alfa"'nın her bir tekil değerine sayısal bir değer vermektir.

table_2:

Load

Alfa,

Autonumber(Alfa) as AlfaNum,

Num

resident table_1;

Karşılaştırma sayısal değerlerle olduğundan, Count( Distinct AlfaNum ) işlemi, Count( Distinct Alfa ) işleminden daha ucuzdur. Daha da ucuz bir yöntem ise otomatik sayı fonksiyonun en son (veya en büyük) sonucunu bulmaktır.

set AlfaDistinctCount = peek( ‘AlfaNum’, -1, ‘table_2’ );

kod içinde veya ifade olarak.

max( AlfaNum)

bir düzen nesnesinde.

If ( Condition(Text),....)

Metin karşılaştırması içeren if cümleleri genellikle pahalıdır. Çözümler örneğin, autonumber kullanarak (bkz. önceki bölümdeki örnekler) ve/veya kod içinde test gerçekleştirerek metni sayılarla eşleştirme şeklinde olabilir.

Metin dizelerinin test edilmesi, sayısal testlerden daha yavaştır. Şu ifadeyi gözden geçirin

If (Alfa= ‘ABC’, ‘ABC’, left (Alfa, 2))

Test işlemi esneklikten herhangi bir şey kaybetmeden, doğrudan kod içinde yapılabilir.

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

İfade şu hale gelir:

If ( Flag = 1,’ABC’, left (Alfa, 2))

ve test işlem çok daha basittir.

Sum ( If (Condition, ‘FieldName’…))

Burada, toplam tablo boyutlarından bağımsızdır ve sonuç tablonun boyutları üzerine dağıtılır. Sorun, test işlemi kod içinde yapılarak ve tabloda toplanarak veya işlemin tamamını kod içinde gerçekleştirerek çözülebilir. Bunun için çok sayıda teknik bulunmaktadır; örneğin interval match, group by, peek, if....then....else.

Bu durum iki aşamayı, yani "Koşul"'un test edilmesini ve sonucun toplanmasını içerir. Önceki örneği sürdürürsek ve toplamayı eklersek

Sum ( If (Alfa= ‘ABC’, Num*1.25 , Num) )

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

İfade şu hale gelir:

Sum ( If ( Flag = 1, Num* 1.25 , Num ) )

Toplama, aynı zamanda aşağıdaki gibi doğrudan kod içinde de yapılabilir:

table_2:

Load

*,

If (Alfa = ‘ABC’, 1, 0) as Flag

resident table_1 ;

table_3:

Load

Alfa,

If ( Flag = 1, Num* 1.25 , Num ) as NewNum

resident table_2 ;

 

table_4:

Load

Alfa,

Sum( NewNum ) as SumNum

resident table_3

group by Alfa ;

Note: Testteki boyut bu olduğundan, toplama Alfa üzerinden yapılır.

If ( Condition, Sum(‘FieldName’)..)

Bu yapı burada yalnızca bir önceki durumla farkı vurgulamak için dahil edilmiştir. Bu toplama işlemi tamamen bağlamsaldır ve, genel anlamda, performans sorunlarına neden olmaz.

If ( Condition1, Sum(‘FieldName’), If (Condition2, Sum(‘FieldName’)……..

İç içe girmiş If...then else... mantığı kavramsal olarak kolaydır; bununla birlikte, yönetici için sıklıkla sorun yaratabilir. Bugüne kadar yüzlerce iç içe girmiş seviyenin olduğu durumlar gördük. Bu, hem bellek için hem de CPU için yoğunluk yaratır. "Koşullar" genellikle dönüştürülerek değiştirilir. Tipik örnek, fiyatın bir değişken olduğu quantity*price toplamasıdır. Bu, "genişletilmiş aralık eşleşmesi" ile çözülebilir. İki koşul da, yani “A VE B” yerine getirilecekse, testin bir “C“ koşuluyla değiştirilmesi gerekebilir.

Örnek:

sum((GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY)

Replaces

Sum(

If((GAC12_EFCT_DT<= GIV23_REJ_DT and

GAC12_EXPIRE_DT>GIV23_REJ_DT) and

(GAC15_EFCT_DT<= GIV23_REJ_DT and GAC15_EXPIRE_DT>GIV23_REJ_DT),

GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null()))

and

Sum(

If(GAC12_EFCT_DT<= GIV23_REJ_DT,

If(GAC12_EXPIRE_DT>GIV23_REJ_DT,

If(GAC15_EFCT_DT<= GIV23_REJ_DT,

If(GAC15_EXPIRE_DT>GIV23_REJ_DT,

(GAC12_STD_COST * GAC15_EXCHANGE_RATE) * GIV24_DISP_QTY,

Null())))))

boyutlar yavaşça değiştirilirken, GAC12_STD_COST ve GAC15_EXCHANGE_RATE alanlarını okunur.

Bkz. Yavaşça değişen boyut sorunlarını çözmek için genişletilmiş intervalmatch söz dizimini kullanma

Metni Sıralama

QlikView, bir Alan'nın sayı, metin veya genel olarak işlenmesi gerektiğini otomatik olarak değerlendirir. Metin olarak değerlendirilen alanlar, metin olarak sıralanır; bu, en yavaş sıralama işlemidir. Bu işlem, yükleme sırasına göre sıralamak için manuel olarak değiştirilebilir. Liste kutularının vb.nin sıralanması gerekmiyorsa bunu kapatın.

QlikView, karışık karakter ve sayılardan oluşan dizeleri alfasayısal sıraya göre sıralar. Yani, geleneksel olan yalnızca ASCII sıralama düzeninin aksine, sayılar değer sırasına göre sıralanırken; sayı olmayanlar ASCII sırasına göre sıralanır. Örnek:

ASCII sıralaması Alfasayısal sıralama
A1 A1
A10 A4
A11 A5
A30 A6
A4 A10
A5 A11
A6 A30

Dinamik Başlıklar ve Metin Nesneleri

Dinamik olarak hesaplanmalı ifadeler, metni girebildiğiniz hemen hemen her yere girilebilir. Bununla birlikte, bir ifadenin değerlendirilmesi için gereken kaynaklar ortamına bağlıdır. İfadeler diyalog penceresinde tanımlanan grafik ve tablolardaki ifadeler, yalnızca nesne görünür olduğunda ve veriler değiştiğinde hesaplanır. Bunlar, örneğin nesne en küçük duruma getirildiğinde hesaplanmaz.

Diğer yandan, nesne başlığı hesaplanırsa, bu hesaplama herhangi bir değişikliğin meydana geldiği her defasında gerçekleştirilir. Ayrıca, gösterme koşullarını, hesaplama koşullarını vb. tanımlamanın birçok yolu vardır. Bu testler de her zaman gerçekleştirilir.

Bazı ifadeler diğerlerinden daha pahalıdır ve ne kadar sık değerlendirilmeleri gerekirse o kadar pahalı hale gelirler. Zaman uyumsuz hesaplamanın getirilmesi, bu davranışı değiştirmiştir ve belki de bunun etkileri uygulamalarınızda daha dikkat çekici bir hal almıştır.

Zaman fonksiyonları, örneğin Now() ve Today(), yeniden hesaplamanın gerektiği her seferinde değerlendirilir. Her saniye uygulamanın yeniden hesaplanmasına neden olacağından, özellikle Now() fonksiyonu oldukça maliyetli olabilir.

Örneğin:

If ( ReloadTime()+3>Now(), 'Old Data', 'New Data')

Dikkate alınabilecek başka bir örnek de aşağıdadır:

If ( ReloadTime()+3>Today(), 'Old Data', 'New Data')

Basit bir test olarak, ifadeleri metin kutularına koyun. Ardından, bunun içinde Now() ile metin kutusunu boyutlandırmayı deneyin.

Makro Tetikleyicileri ("on change")

Makrolar, uygulamada meydana gelen neredeyse her türlü olayla tetiklenebilecek şekilde ayarlanabilir. Bir olayın dönüşümlü olarak diğer bir olayı tetiklediği basamaklı veya özyinelemeli olaylara dikkat edin.